001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021
022public class ShearFilter extends TransformFilter {
023
024        private float xangle = 0.0f;
025        private float yangle = 0.0f;
026        private float shx = 0.0f;
027        private float shy = 0.0f;
028        private float xoffset = 0.0f;
029        private float yoffset = 0.0f;
030        private boolean resize = true;
031
032        public ShearFilter() {
033        }
034
035        public void setResize(boolean resize) {
036                this.resize = resize;
037        }
038
039        public boolean isResize() {
040                return resize;
041        }
042
043        public void setXAngle(float xangle) {
044                this.xangle = xangle;
045                initialize();
046        }
047
048        public float getXAngle() {
049                return xangle;
050        }
051
052        public void setYAngle(float yangle) {
053                this.yangle = yangle;
054                initialize();
055        }
056
057        public float getYAngle() {
058                return yangle;
059        }
060
061        private void initialize() {
062                shx = (float)Math.sin(xangle);
063                shy = (float)Math.sin(yangle);
064        }
065        
066        protected void transformSpace(Rectangle r) {
067                float tangent = (float)Math.tan(xangle);
068                xoffset = -r.height * tangent;
069                if (tangent < 0.0)
070                        tangent = -tangent;
071                r.width = (int)(r.height * tangent + r.width + 0.999999f);
072                tangent = (float)Math.tan(yangle);
073                yoffset = -r.width * tangent;
074                if (tangent < 0.0)
075                        tangent = -tangent;
076                r.height = (int)(r.width * tangent + r.height + 0.999999f);
077        }
078
079/*
080        public void imageComplete(int status) {
081try {
082                if (status == IMAGEERROR || status == IMAGEABORTED) {
083                        consumer.imageComplete(status);
084                        return;
085                }
086
087                int width = originalSpace.width;
088                int height = originalSpace.height;
089
090                float tangent = Math.tan(angle);
091                if (tangent < 0.0)
092                        tangent = -tangent;
093                int newWidth = (int)(height * tangent + width + 0.999999);
094                int[] outPixels = new int[height*newWidth];
095                int inIndex = 0;
096                int yOffset = 0;
097                for (int y = 0; y < height; y++) {
098                        float newCol;
099                        if (angle >= 0.0)
100                                newCol = y * tangent;
101                        else
102                                newCol = (height-y) * tangent;
103                        int iNewCol = (int)newCol;
104                        float f = newCol - iNewCol;
105                        f = 1.0 - f;
106
107                        int outIndex = yOffset+iNewCol;
108                        int lastRGB = inPixels[inIndex];
109                        for (int x = 0; x < width; x++) {
110                                int rgb = inPixels[inIndex];
111                                outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, rgb);
112                                lastRGB = rgb;
113                                inIndex++;
114                                outIndex++;
115                        }
116                        outPixels[outIndex] = ImageMath.mixColors(f, lastRGB, 0);
117                        yOffset += newWidth;
118                }
119                consumer.setPixels(0, 0, newWidth, height, defaultRGBModel, outPixels, 0, newWidth);
120                consumer.imageComplete(status);
121                inPixels = null;
122}
123catch (Exception e) {
124        e.printStackTrace();
125}
126        }
127*/
128        
129        protected void transformInverse(int x, int y, float[] out) {
130                out[0] = x + xoffset + (y * shx);
131                out[1] = y + yoffset + (x * shy);
132        }
133
134        public String toString() {
135                return "Distort/Shear...";
136        }
137
138}