001 /* 002 * 003 004 Licensed under the Apache License, Version 2.0 (the "License"); 005 you may not use this file except in compliance with the License. 006 You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010 Unless required by applicable law or agreed to in writing, software 011 distributed under the License is distributed on an "AS IS" BASIS, 012 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 See the License for the specific language governing permissions and 014 limitations under the License. 015 */ 016 017 package railo.runtime.img.filter;import java.awt.image.BufferedImage; 018 019 import railo.runtime.engine.ThreadLocalPageContext; 020 import railo.runtime.exp.FunctionException; 021 import railo.runtime.exp.PageException; 022 import railo.runtime.img.ImageUtil; 023 import railo.runtime.type.KeyImpl; 024 import railo.runtime.type.Struct; 025 import railo.runtime.type.util.CollectionUtil; 026 027 028 029 public class FadeFilter extends PointFilter implements DynFiltering { 030 031 //private int width, height; 032 private float angle = 0.0f; 033 private float fadeStart = 1.0f; 034 private float fadeWidth = 10.0f; 035 private int sides; 036 private boolean invert; 037 private float m00 = 1.0f; 038 private float m01 = 0.0f; 039 private float m10 = 0.0f; 040 private float m11 = 1.0f; 041 042 /** 043 * Specifies the angle of the texture. 044 * @param angle the angle of the texture. 045 * @angle 046 * @see #getAngle 047 */ 048 public void setAngle(float angle) { 049 this.angle = angle; 050 float cos = (float)Math.cos(angle); 051 float sin = (float)Math.sin(angle); 052 m00 = cos; 053 m01 = sin; 054 m10 = -sin; 055 m11 = cos; 056 } 057 058 /** 059 * Returns the angle of the texture. 060 * @return the angle of the texture. 061 * @see #setAngle 062 */ 063 public float getAngle() { 064 return angle; 065 } 066 067 public void setSides(int sides) { 068 this.sides = sides; 069 } 070 071 public int getSides() { 072 return sides; 073 } 074 075 public void setFadeStart(float fadeStart) { 076 this.fadeStart = fadeStart; 077 } 078 079 public float getFadeStart() { 080 return fadeStart; 081 } 082 083 public void setFadeWidth(float fadeWidth) { 084 this.fadeWidth = fadeWidth; 085 } 086 087 public float getFadeWidth() { 088 return fadeWidth; 089 } 090 091 public void setInvert(boolean invert) { 092 this.invert = invert; 093 } 094 095 public boolean getInvert() { 096 return invert; 097 } 098 099 public void setDimensions(int width, int height) { 100 //this.width = width; 101 //this.height = height; 102 super.setDimensions(width, height); 103 } 104 105 public int filterRGB(int x, int y, int rgb) { 106 float nx = m00*x + m01*y; 107 float ny = m10*x + m11*y; 108 if (sides == 2) 109 nx = (float)Math.sqrt(nx*nx + ny*ny); 110 else if (sides == 3) 111 nx = ImageMath.mod(nx, 16); 112 else if (sides == 4) 113 nx = symmetry(nx, 16); 114 int alpha = (int)(ImageMath.smoothStep(fadeStart, fadeStart+fadeWidth, nx) * 255); 115 if (invert) 116 alpha = 255-alpha; 117 return (alpha << 24) | (rgb & 0x00ffffff); 118 } 119 120 public float symmetry(float x, float b) { 121 /* 122 int d = (int)(x / b); 123 x = ImageMath.mod(x, b); 124 if ((d & 1) == 1) 125 return b-x; 126 return x; 127 */ 128 x = ImageMath.mod(x, 2*b); 129 if (x > b) 130 return 2*b-x; 131 return x; 132 } 133 134 /* 135 public float star(float x, float y, int sides, float rMin, float rMax) { 136 float sideAngle = 2*Math.PI / sides; 137 float angle = Math.atan2(y, x); 138 float r = Math.sqrt(x*x + y*y); 139 float t = ImageMath.mod(angle, sideAngle) / sideAngle; 140 if (t > 0.5) 141 t = 1.0-t; 142 } 143 */ 144 145 public String toString() { 146 return "Fade..."; 147 } 148 149 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 150 Object o; 151 if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle")); 152 if((o=parameters.removeEL(KeyImpl.init("Sides")))!=null)setSides(ImageFilterUtil.toIntValue(o,"Sides")); 153 if((o=parameters.removeEL(KeyImpl.init("FadeStart")))!=null)setFadeStart(ImageFilterUtil.toFloatValue(o,"FadeStart")); 154 if((o=parameters.removeEL(KeyImpl.init("FadeWidth")))!=null)setFadeWidth(ImageFilterUtil.toFloatValue(o,"FadeWidth")); 155 if((o=parameters.removeEL(KeyImpl.init("Invert")))!=null)setInvert(ImageFilterUtil.toBooleanValue(o,"Invert")); 156 if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){ 157 int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions"); 158 setDimensions(dim[0],dim[1]); 159 } 160 161 // check for arguments not supported 162 if(parameters.size()>0) { 163 throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+CollectionUtil.getKeyList(parameters,", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [Angle, Sides, FadeStart, FadeWidth, Invert, Dimensions]"); 164 } 165 166 return filter(src, dst); 167 } 168 } 169