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.Color;
036import java.awt.Graphics2D;
037import java.awt.Paint;
038import java.awt.geom.AffineTransform;
039import java.awt.image.BufferedImage;
040
041import lucee.runtime.engine.ThreadLocalPageContext;
042import lucee.runtime.exp.FunctionException;
043import lucee.runtime.exp.PageException;
044import lucee.runtime.img.ImageUtil;
045import lucee.runtime.type.KeyImpl;
046import lucee.runtime.type.Struct;
047import lucee.runtime.type.util.CollectionUtil;
048
049/**
050 * A filter to add a border around an image using the supplied Paint, which may be null for no painting.
051 */
052public class BorderFilter extends AbstractBufferedImageOp  implements DynFiltering {
053
054        private int leftBorder, rightBorder;
055        private int topBorder, bottomBorder;
056        private Paint borderPaint;
057
058    /**
059     * Construct a BorderFilter which does nothing.
060     */
061        public BorderFilter() {
062        }
063
064    /**
065     * Construct a BorderFilter.
066         * @param leftBorder the left border value
067         * @param topBorder the top border value
068         * @param rightBorder the right border value
069         * @param bottomBorder the bottom border value
070         * @param borderPaint the paint with which to fill the border
071     */
072        public BorderFilter( int leftBorder, int topBorder, int rightBorder, int bottomBorder, Paint borderPaint ) {
073                this.leftBorder = leftBorder;
074                this.topBorder = topBorder;
075                this.rightBorder = rightBorder;
076                this.bottomBorder = bottomBorder;
077                this.borderPaint = borderPaint;
078        }
079
080        /**
081         * Set the border size on the left edge.
082         * @param leftBorder the number of pixels of border to add to the edge
083     * @min-value 0
084     * @see #getLeftBorder
085         */
086        public void setLeft(int leftBorder) {
087                this.leftBorder = leftBorder;
088        }
089        
090    /**
091     * Returns the left border value.
092     * @return the left border value.
093     * @see #setLeftBorder
094     */
095        public int getLeftBorder() {
096                return leftBorder;
097        }
098        
099        /**
100         * Set the border size on the right edge.
101         * @param rightBorder the number of pixels of border to add to the edge
102     * @min-value 0
103     * @see #getRightBorder
104         */
105        public void setRight(int rightBorder) {
106                this.rightBorder = rightBorder;
107        }
108        
109    /**
110     * Returns the right border value.
111     * @return the right border value.
112     * @see #setRightBorder
113     */
114        public int getRightBorder() {
115                return rightBorder;
116        }
117        
118        /**
119         * Set the border size on the top edge.
120         * @param topBorder the number of pixels of border to add to the edge
121     * @min-value 0
122     * @see #getTopBorder
123         */
124        public void setTop(int topBorder) {
125                this.topBorder = topBorder;
126        }
127
128    /**
129     * Returns the top border value.
130     * @return the top border value.
131     * @see #setTopBorder
132     */
133        public int getTopBorder() {
134                return topBorder;
135        }
136
137        /**
138         * Set the border size on the bottom edge.
139         * @param bottomBorder the number of pixels of border to add to the edge
140     * @min-value 0
141     * @see #getBottomBorder
142         */
143        public void setBottom(int bottomBorder) {
144                this.bottomBorder = bottomBorder;
145        }
146
147    /**
148     * Returns the border border value.
149     * @return the border border value.
150     * @see #setBottomBorder
151     */
152        public int getBottomBorder() {
153                return bottomBorder;
154        }
155
156        /**
157         * Set the border color.
158         * @param borderColor the color with which to fill the border
159         */
160        public void setColor( Color borderColor ) {
161                this.borderPaint = borderColor;
162        }
163
164        /**
165         * Get the border paint.
166         * @return the paint with which to fill the border
167     * @see #setBorderPaint
168         */
169        public Paint getBorderPaint() {
170                return borderPaint;
171        }
172
173        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
174                int width = src.getWidth();
175                int height = src.getHeight();
176
177                int totalWidth=width+leftBorder+rightBorder;
178                int totalHeight=height+topBorder+bottomBorder;
179                
180                dst=ImageUtil.createBufferedImage(src,totalWidth,totalHeight);
181                
182                
183                Graphics2D g = dst.createGraphics();
184                if ( borderPaint != null ) {
185                        g.setPaint( borderPaint );
186                        if ( leftBorder > 0 )        g.fillRect( 0, 0, leftBorder, totalHeight );
187                        if ( rightBorder > 0 )       g.fillRect( totalWidth-rightBorder, 0, rightBorder, totalHeight );
188                        if ( topBorder > 0 ) g.fillRect( leftBorder, 0, totalWidth-leftBorder-rightBorder, topBorder );
189                        if ( bottomBorder > 0 )      g.fillRect( leftBorder, totalHeight-bottomBorder, totalWidth-leftBorder-rightBorder, bottomBorder );
190                }
191                g.drawRenderedImage( src, AffineTransform.getTranslateInstance( leftBorder, rightBorder ) );
192                g.dispose();
193                return dst;
194        }
195
196        public String toString() {
197                return "Distort/Border...";
198        }
199        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {
200                
201                Object o;
202                if((o=parameters.removeEL(KeyImpl.init("Left")))!=null)setLeft(ImageFilterUtil.toIntValue(o,"Left"));
203                if((o=parameters.removeEL(KeyImpl.init("Right")))!=null)setRight(ImageFilterUtil.toIntValue(o,"Right"));
204                if((o=parameters.removeEL(KeyImpl.init("Top")))!=null)setTop(ImageFilterUtil.toIntValue(o,"Top"));
205                if((o=parameters.removeEL(KeyImpl.init("Bottom")))!=null)setBottom(ImageFilterUtil.toIntValue(o,"Bottom"));
206                if((o=parameters.removeEL(KeyImpl.init("Color")))!=null)setColor(ImageFilterUtil.toColor(o,"Color"));
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 [LeftBorder, RightBorder, TopBorder, BottomBorder, BorderPaint]");
211                }
212                
213                
214                //BufferedImage dst=ImageUtil.createBufferedImage(src);
215                
216                
217                return filter(src, (BufferedImage)null);
218        }
219}