1 18 package org.apache.batik.ext.awt.image.renderable; 19 20 import java.awt.Rectangle ; 21 import java.awt.RenderingHints ; 22 import java.awt.Shape ; 23 import java.awt.geom.AffineTransform ; 24 import java.awt.geom.Rectangle2D ; 25 import java.awt.image.RenderedImage ; 26 import java.awt.image.renderable.RenderContext ; 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.PadRed; 35 import org.apache.batik.ext.awt.image.rendered.SpecularLightingRed; 36 37 43 public class SpecularLightingRable8Bit 44 extends AbstractColorInterpolationRable 45 implements SpecularLightingRable { 46 49 private double surfaceScale; 50 51 54 private double ks; 55 56 59 private double specularExponent; 60 61 64 private Light light; 65 66 69 private Rectangle2D litRegion; 70 71 74 private float [] kernelUnitLength = null; 75 76 public SpecularLightingRable8Bit(Filter src, 77 Rectangle2D litRegion, 78 Light light, 79 double ks, 80 double specularExponent, 81 double surfaceScale, 82 double [] kernelUnitLength) { 83 super(src, null); 84 setLight(light); 85 setKs(ks); 86 setSpecularExponent(specularExponent); 87 setSurfaceScale(surfaceScale); 88 setLitRegion(litRegion); 89 setKernelUnitLength(kernelUnitLength); 90 } 91 92 95 public Filter getSource(){ 96 return (Filter)getSources().get(0); 97 } 98 99 102 public void setSource(Filter src){ 103 init(src, null); 104 } 105 106 109 public Rectangle2D getBounds2D(){ 110 return (Rectangle2D )(litRegion.clone()); 111 } 112 113 116 public Rectangle2D getLitRegion(){ 117 return getBounds2D(); 118 } 119 120 123 public void setLitRegion(Rectangle2D litRegion){ 124 touch(); 125 this.litRegion = litRegion; 126 } 127 128 131 public Light getLight(){ 132 return light; 133 } 134 135 138 public void setLight(Light light){ 139 touch(); 140 this.light = light; 141 } 142 143 146 public double getSurfaceScale(){ 147 return surfaceScale; 148 } 149 150 153 public void setSurfaceScale(double surfaceScale){ 154 touch(); 155 this.surfaceScale = surfaceScale; 156 } 157 158 161 public double getKs(){ 162 return ks; 163 } 164 165 168 public void setKs(double ks){ 169 touch(); 170 this.ks = ks; 171 } 172 173 176 public double getSpecularExponent(){ 177 return specularExponent; 178 } 179 180 183 public void setSpecularExponent(double specularExponent){ 184 touch(); 185 this.specularExponent = specularExponent; 186 } 187 188 192 public double [] getKernelUnitLength() { 193 if (kernelUnitLength == null) 194 return null; 195 196 double [] ret = new double[2]; 197 ret[0] = kernelUnitLength[0]; 198 ret[1] = kernelUnitLength[1]; 199 return ret; 200 } 201 202 206 public void setKernelUnitLength(double [] kernelUnitLength) { 207 touch(); 208 if (kernelUnitLength == null) { 209 this.kernelUnitLength = null; 210 return; 211 } 212 213 if (this.kernelUnitLength == null) 214 this.kernelUnitLength = new float[2]; 215 216 this.kernelUnitLength[0] = (float)kernelUnitLength[0]; 217 this.kernelUnitLength[1] = (float)kernelUnitLength[1]; 218 } 219 220 public RenderedImage createRendering(RenderContext rc){ 221 Shape aoi = rc.getAreaOfInterest(); 222 if (aoi == null) 223 aoi = getBounds2D(); 224 225 Rectangle2D aoiR = aoi.getBounds2D(); 226 Rectangle2D.intersect(aoiR, getBounds2D(), aoiR); 227 228 AffineTransform at = rc.getTransform(); 229 Rectangle devRect = at.createTransformedShape(aoiR).getBounds(); 230 231 if(devRect.width == 0 || devRect.height == 0){ 232 return null; 233 } 234 235 double sx = at.getScaleX(); 245 double sy = at.getScaleY(); 246 247 double shx = at.getShearX(); 248 double shy = at.getShearY(); 249 250 double tx = at.getTranslateX(); 251 double ty = at.getTranslateY(); 252 253 double scaleX = Math.sqrt(sx*sx + shy*shy); 255 double scaleY = Math.sqrt(sy*sy + shx*shx); 256 257 if(scaleX == 0 || scaleY == 0){ 258 return null; 260 } 261 262 if (kernelUnitLength != null) { 265 if (scaleX >= 1/kernelUnitLength[0]) 266 scaleX = 1/kernelUnitLength[0]; 267 268 if (scaleY >= 1/kernelUnitLength[1]) 269 scaleY = 1/kernelUnitLength[1]; 270 } 271 272 AffineTransform scale = 273 AffineTransform.getScaleInstance(scaleX, scaleY); 274 275 devRect = scale.createTransformedShape(aoiR).getBounds(); 276 277 aoiR.setRect(aoiR.getX() -(2/scaleX), 279 aoiR.getY() -(2/scaleY), 280 aoiR.getWidth() +(4/scaleX), 281 aoiR.getHeight()+(4/scaleY)); 282 283 284 rc = (RenderContext )rc.clone(); 286 rc.setAreaOfInterest(aoiR); 287 rc.setTransform(scale); 288 289 291 CachableRed cr; 292 cr = GraphicsUtil.wrap(getSource().createRendering(rc)); 293 294 BumpMap bumpMap = new BumpMap(cr, surfaceScale, scaleX, scaleY); 295 296 cr = new SpecularLightingRed(ks, specularExponent, light, bumpMap, 297 devRect, 1/scaleX, 1/scaleY, 298 isColorSpaceLinear()); 299 300 AffineTransform shearAt = 302 new AffineTransform (sx/scaleX, shy/scaleX, 303 shx/scaleY, sy/scaleY, 304 tx, ty); 305 306 if(!shearAt.isIdentity()) { 307 RenderingHints rh = rc.getRenderingHints(); 308 Rectangle padRect = new Rectangle (devRect.x-1, devRect.y-1, 309 devRect.width+2, 310 devRect.height+2); 311 cr = new PadRed(cr, padRect, PadMode.REPLICATE, rh); 312 313 cr = new AffineRed(cr, shearAt, rh); 314 } 315 316 return cr; 317 } 318 } 319 320 | Popular Tags |