KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > ext > awt > image > renderable > DiffuseLightingRable8Bit


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.ext.awt.image.renderable;
19
20 import java.awt.Rectangle JavaDoc;
21 import java.awt.RenderingHints JavaDoc;
22 import java.awt.Shape 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
28 import org.apache.batik.ext.awt.image.GraphicsUtil;
29 import org.apache.batik.ext.awt.image.Light;
30 import org.apache.batik.ext.awt.image.PadMode;
31 import org.apache.batik.ext.awt.image.rendered.AffineRed;
32 import org.apache.batik.ext.awt.image.rendered.BumpMap;
33 import org.apache.batik.ext.awt.image.rendered.CachableRed;
34 import org.apache.batik.ext.awt.image.rendered.DiffuseLightingRed;
35 import org.apache.batik.ext.awt.image.rendered.PadRed;
36
37 /**
38  * Implementation of the DiffuseLightRable interface.
39  *
40  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
41  * @version $Id: DiffuseLightingRable8Bit.java,v 1.15 2005/03/27 08:58:33 cam Exp $
42  */

43 public class DiffuseLightingRable8Bit
44     extends AbstractColorInterpolationRable
45     implements DiffuseLightingRable {
46     /**
47      * Surface Scale
48      */

49     private double surfaceScale;
50
51     /**
52      * Diffuse constant
53      */

54     private double kd;
55
56     /**
57      * Light used for the diffuse lighting computations
58      */

59     private Light light;
60
61     /**
62      * Lit Area
63      */

64     private Rectangle2D JavaDoc litRegion;
65
66     /**
67      * The dx/dy to use in user space for the sobel gradient.
68      */

69     private float [] kernelUnitLength = null;
70
71     public DiffuseLightingRable8Bit(Filter src,
72                                     Rectangle2D JavaDoc litRegion,
73                                     Light light,
74                                     double kd,
75                                     double surfaceScale,
76                                     double [] kernelUnitLength) {
77         super(src, null);
78         setLight(light);
79         setKd(kd);
80         setSurfaceScale(surfaceScale);
81         setLitRegion(litRegion);
82         setKernelUnitLength(kernelUnitLength);
83     }
84
85     /**
86      * Returns the source to be filtered
87      */

88     public Filter getSource(){
89         return (Filter)getSources().get(0);
90     }
91
92     /**
93      * Sets the source to be filtered
94      */

95     public void setSource(Filter src){
96         init(src, null);
97     }
98
99     /**
100      * Returns this filter's bounds
101      */

102     public Rectangle2D JavaDoc getBounds2D(){
103         return (Rectangle2D JavaDoc)(litRegion.clone());
104     }
105
106     /**
107      * Returns this filter's litRegion
108      */

109     public Rectangle2D JavaDoc getLitRegion(){
110         return getBounds2D();
111     }
112
113     /**
114      * Set this filter's litRegion
115      */

116     public void setLitRegion(Rectangle2D JavaDoc litRegion){
117         touch();
118         this.litRegion = litRegion;
119     }
120
121     /**
122      * @return Light object used for the diffuse lighting
123      */

124     public Light getLight(){
125         return light;
126     }
127
128     /**
129      * @param light New Light object
130      */

131     public void setLight(Light light){
132         touch();
133         this.light = light;
134     }
135
136     /**
137      * @return surfaceScale
138      */

139     public double getSurfaceScale(){
140         return surfaceScale;
141     }
142
143     /**
144      * Sets the surface scale
145      */

146     public void setSurfaceScale(double surfaceScale){
147         touch();
148         this.surfaceScale = surfaceScale;
149     }
150
151     /**
152      * @return diffuse constant, or kd.
153      */

154     public double getKd(){
155         return kd;
156     }
157
158     /**
159      * Sets the diffuse constant, or kd
160      */

161     public void setKd(double kd){
162         touch();
163         this.kd = kd;
164     }
165
166     /**
167      * Returns the min [dx,dy] distance in user space for evalutation of
168      * the sobel gradient.
169      */

170     public double [] getKernelUnitLength() {
171         if (kernelUnitLength == null)
172             return null;
173
174         double [] ret = new double[2];
175         ret[0] = kernelUnitLength[0];
176         ret[1] = kernelUnitLength[1];
177         return ret;
178     }
179
180     /**
181      * Sets the min [dx,dy] distance in user space for evaluation of the
182      * sobel gradient. If set to zero or null then device space will be used.
183      */

184     public void setKernelUnitLength(double [] kernelUnitLength) {
185         touch();
186         if (kernelUnitLength == null) {
187             this.kernelUnitLength = null;
188             return;
189         }
190
191         if (this.kernelUnitLength == null)
192             this.kernelUnitLength = new float[2];
193
194         this.kernelUnitLength[0] = (float)kernelUnitLength[0];
195         this.kernelUnitLength[1] = (float)kernelUnitLength[1];
196     }
197
198     public RenderedImage JavaDoc createRendering(RenderContext JavaDoc rc) {
199         Shape JavaDoc aoi = rc.getAreaOfInterest();
200         if (aoi == null)
201             aoi = getBounds2D();
202
203         Rectangle2D JavaDoc aoiR = aoi.getBounds2D();
204         Rectangle2D.intersect(aoiR, getBounds2D(), aoiR);
205
206         AffineTransform JavaDoc at = rc.getTransform();
207         Rectangle JavaDoc devRect = at.createTransformedShape(aoiR).getBounds();
208
209         if(devRect.width == 0 || devRect.height == 0){
210             return null;
211         }
212
213         //
214
// DiffuseLightingRed only operates on a scaled space.
215
// The following extracts the scale portion of the
216
// user to device transform
217
//
218
// The source is rendered with the scale-only transform
219
// and the rendered result is used as a bumpMap for the
220
// DiffuseLightingRed filter.
221
//
222
double sx = at.getScaleX();
223         double sy = at.getScaleY();
224
225         double shx = at.getShearX();
226         double shy = at.getShearY();
227
228         double tx = at.getTranslateX();
229         double ty = at.getTranslateY();
230
231          // The Scale is the "hypotonose" of the matrix vectors.
232
double scaleX = Math.sqrt(sx*sx + shy*shy);
233         double scaleY = Math.sqrt(sy*sy + shx*shx);
234
235         if(scaleX == 0 || scaleY == 0){
236             // Non invertible transform
237
return null;
238         }
239
240         // These values represent the scale factor to the intermediate
241
// coordinate system where we will apply our convolution.
242
if (kernelUnitLength != null) {
243             if ((kernelUnitLength[0] > 0) &&
244                 (scaleX > 1/kernelUnitLength[0]))
245                 scaleX = 1/kernelUnitLength[0];
246
247             if ((kernelUnitLength[1] > 0) &&
248                 (scaleY > 1/kernelUnitLength[1]))
249                 scaleY = 1/kernelUnitLength[1];
250         }
251
252         AffineTransform JavaDoc scale =
253             AffineTransform.getScaleInstance(scaleX, scaleY);
254
255         devRect = scale.createTransformedShape(aoiR).getBounds();
256
257         // Grow for surround needs of bump map.
258
aoiR.setRect(aoiR.getX() -(2/scaleX),
259                      aoiR.getY() -(2/scaleY),
260                      aoiR.getWidth() +(4/scaleX),
261                      aoiR.getHeight()+(4/scaleY));
262
263
264         // Build texture from the source
265
rc = (RenderContext JavaDoc)rc.clone();
266         rc.setAreaOfInterest(aoiR);
267         rc.setTransform(scale);
268
269         // System.out.println("scaleX / scaleY : " + scaleX + "/" + scaleY);
270

271         CachableRed cr;
272         cr = GraphicsUtil.wrap(getSource().createRendering(rc));
273
274         BumpMap bumpMap = new BumpMap(cr, surfaceScale, scaleX, scaleY);
275
276         cr = new DiffuseLightingRed(kd, light, bumpMap,
277                                     devRect, 1/scaleX, 1/scaleY,
278                                     isColorSpaceLinear());
279
280         // Return sheared/rotated tiled image
281
AffineTransform JavaDoc shearAt =
282             new AffineTransform JavaDoc(sx/scaleX, shy/scaleX,
283                                 shx/scaleY, sy/scaleY,
284                                 tx, ty);
285
286         if(!shearAt.isIdentity()) {
287             RenderingHints JavaDoc rh = rc.getRenderingHints();
288             Rectangle JavaDoc padRect = new Rectangle JavaDoc(devRect.x-1, devRect.y-1,
289                                               devRect.width+2,
290                                               devRect.height+2);
291             cr = new PadRed(cr, padRect, PadMode.REPLICATE, rh);
292
293             cr = new AffineRed(cr, shearAt, rh);
294         }
295
296         return cr;
297     }
298 }
299
300
Popular Tags