001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019/*
020*
021
022Licensed under the Apache License, Version 2.0 (the "License");
023you may not use this file except in compliance with the License.
024You may obtain a copy of the License at
025
026   http://www.apache.org/licenses/LICENSE-2.0
027
028Unless required by applicable law or agreed to in writing, software
029distributed under the License is distributed on an "AS IS" BASIS,
030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
031See the License for the specific language governing permissions and
032limitations under the License.
033*/
034
035package lucee.runtime.img.filter;import java.awt.image.BufferedImage;
036
037import lucee.runtime.engine.ThreadLocalPageContext;
038import lucee.runtime.exp.FunctionException;
039import lucee.runtime.exp.PageException;
040import lucee.runtime.img.ImageUtil;
041import lucee.runtime.type.KeyImpl;
042import lucee.runtime.type.Struct;
043import lucee.runtime.type.util.CollectionUtil;
044
045/**
046 * A Filter to draw grids and check patterns.
047 */
048public class CheckFilter extends PointFilter  implements DynFiltering {
049
050        private int xScale = 8;
051        private int yScale = 8;
052        private int foreground = 0xffffffff;
053        private int background = 0xff000000;
054        private int fuzziness = 0;
055        private float angle = 0.0f;
056        private float m00 = 1.0f;
057        private float m01 = 0.0f;
058        private float m10 = 0.0f;
059        private float m11 = 1.0f;
060
061        public CheckFilter() {
062        }
063
064        /**
065     * Set the foreground color.
066     * @param foreground the color.
067     * @see #getForeground
068     */
069        public void setForeground(int foreground) {
070                this.foreground = foreground;
071        }
072
073        /**
074     * Get the foreground color.
075     * @return the color.
076     * @see #setForeground
077     */
078        public int getForeground() {
079                return foreground;
080        }
081
082        /**
083     * Set the background color.
084     * @param background the color.
085     * @see #getBackground
086     */
087        public void setBackground(int background) {
088                this.background = background;
089        }
090
091        /**
092     * Get the background color.
093     * @return the color.
094     * @see #setBackground
095     */
096        public int getBackground() {
097                return background;
098        }
099
100        /**
101     * Set the X scale of the texture.
102     * @param xScale the scale.
103     * @see #getXScale
104     */
105        public void setXScale(int xScale) {
106                this.xScale = xScale;
107        }
108
109        /**
110     * Get the X scale of the texture.
111     * @return the scale.
112     * @see #setXScale
113     */
114        public int getXScale() {
115                return xScale;
116        }
117
118        /**
119     * Set the Y scale of the texture.
120     * @param yScale the scale.
121     * @see #getYScale
122     */
123        public void setYScale(int yScale) {
124                this.yScale = yScale;
125        }
126
127        /**
128     * Get the Y scale of the texture.
129     * @return the scale.
130     * @see #setYScale
131     */
132        public int getYScale() {
133                return yScale;
134        }
135
136        /**
137     * Set the fuzziness of the texture.
138     * @param fuzziness the fuzziness.
139     * @see #getFuzziness
140     */
141        public void setFuzziness(int fuzziness) {
142                this.fuzziness = fuzziness;
143        }
144
145        /**
146     * Get the fuzziness of the texture.
147     * @return the fuzziness.
148     * @see #setFuzziness
149     */
150        public int getFuzziness() {
151                return fuzziness;
152        }
153
154        /**
155     * Set the angle of the texture.
156     * @param angle the angle of the texture.
157     * @angle
158     * @see #getAngle
159     */
160        public void setAngle(float angle) {
161                this.angle = angle;
162                float cos = (float)Math.cos(angle);
163                float sin = (float)Math.sin(angle);
164                m00 = cos;
165                m01 = sin;
166                m10 = -sin;
167                m11 = cos;
168        }
169
170        /**
171     * Get the angle of the texture.
172     * @return the angle of the texture.
173     * @see #setAngle
174     */
175        public float getAngle() {
176                return angle;
177        }
178
179        public int filterRGB(int x, int y, int rgb) {
180                float nx = (m00*x + m01*y) / xScale;
181                float ny = (m10*x + m11*y) / yScale;
182                float f = ((int)(nx+100000) % 2 != (int)(ny+100000) % 2) ? 1.0f : 0.0f;
183                if (fuzziness != 0) {
184                        float fuzz = (fuzziness/100.0f);
185                        float fx = ImageMath.smoothPulse(0, fuzz, 1-fuzz, 1, ImageMath.mod(nx, 1));
186                        float fy = ImageMath.smoothPulse(0, fuzz, 1-fuzz, 1, ImageMath.mod(ny, 1));
187                        f *= fx*fy;
188                }
189                return ImageMath.mixColors(f, foreground, background);
190        }
191
192        public String toString() {
193                return "Texture/Checkerboard...";
194        }
195        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
196                Object o;
197                if((o=parameters.removeEL(KeyImpl.init("Angle")))!=null)setAngle(ImageFilterUtil.toFloatValue(o,"Angle"));
198                if((o=parameters.removeEL(KeyImpl.init("XScale")))!=null)setXScale(ImageFilterUtil.toIntValue(o,"XScale"));
199                if((o=parameters.removeEL(KeyImpl.init("YScale")))!=null)setYScale(ImageFilterUtil.toIntValue(o,"YScale"));
200                if((o=parameters.removeEL(KeyImpl.init("Fuzziness")))!=null)setFuzziness(ImageFilterUtil.toIntValue(o,"Fuzziness"));
201                if((o=parameters.removeEL(KeyImpl.init("Foreground")))!=null)setForeground(ImageFilterUtil.toColorRGB(o,"Foreground"));
202                if((o=parameters.removeEL(KeyImpl.init("Background")))!=null)setBackground(ImageFilterUtil.toColorRGB(o,"Background"));
203                if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){
204                        int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions");
205                        setDimensions(dim[0],dim[1]);
206                }
207
208                // check for arguments not supported
209                if(parameters.size()>0) {
210                        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, XScale, YScale, Fuzziness, Foreground, Background, Dimensions]");
211                }
212
213                return filter(src, dst);
214        }
215}
216