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 WeaveFilter extends PointFilter {
023
024        private float xWidth = 16;
025        private float yWidth = 16;
026        private float xGap = 6;
027        private float yGap = 6;
028        private int rows = 4;
029        private int cols = 4;
030        private int rgbX = 0xffff8080;
031        private int rgbY = 0xff8080ff;
032        private boolean useImageColors = true;
033        private boolean roundThreads = false;
034        private boolean shadeCrossings = true;
035
036        public int[][] matrix = {
037                { 0, 1, 0, 1 },
038                { 1, 0, 1, 0 },
039                { 0, 1, 0, 1 },
040                { 1, 0, 1, 0 },
041        };
042        
043        public WeaveFilter() {
044        }
045        
046        public void setXGap(float xGap) {
047                this.xGap = xGap;
048        }
049
050        public void setXWidth(float xWidth) {
051                this.xWidth = xWidth;
052        }
053
054        public float getXWidth() {
055                return xWidth;
056        }
057
058        public void setYWidth(float yWidth) {
059                this.yWidth = yWidth;
060        }
061
062        public float getYWidth() {
063                return yWidth;
064        }
065
066        public float getXGap() {
067                return xGap;
068        }
069
070        public void setYGap(float yGap) {
071                this.yGap = yGap;
072        }
073
074        public float getYGap() {
075                return yGap;
076        }
077
078        public void setCrossings(int[][] matrix) {
079                this.matrix = matrix;
080        }
081        
082        public int[][] getCrossings() {
083                return matrix;
084        }
085        
086        public void setUseImageColors(boolean useImageColors) {
087                this.useImageColors = useImageColors;
088        }
089
090        public boolean getUseImageColors() {
091                return useImageColors;
092        }
093
094        public void setRoundThreads(boolean roundThreads) {
095                this.roundThreads = roundThreads;
096        }
097
098        public boolean getRoundThreads() {
099                return roundThreads;
100        }
101
102        public void setShadeCrossings(boolean shadeCrossings) {
103                this.shadeCrossings = shadeCrossings;
104        }
105
106        public boolean getShadeCrossings() {
107                return shadeCrossings;
108        }
109
110        public int filterRGB(int x, int y, int rgb) {
111                x += xWidth+xGap/2;
112                y += yWidth+yGap/2;
113                float nx = ImageMath.mod(x, xWidth+xGap);
114                float ny = ImageMath.mod(y, yWidth+yGap);
115                int ix = (int)(x / (xWidth+xGap));
116                int iy = (int)(y / (yWidth+yGap));
117                boolean inX = nx < xWidth;
118                boolean inY = ny < yWidth;
119                float dX, dY;
120                float cX, cY;
121                int lrgbX, lrgbY;
122
123                if (roundThreads) {
124                        dX = Math.abs(xWidth/2-nx) / xWidth / 2;
125                        dY = Math.abs(yWidth/2-ny) / yWidth / 2;
126                } else {
127                        dX = dY = 0;
128                }
129
130                if (shadeCrossings) {
131                        cX = ImageMath.smoothStep(xWidth/2, xWidth/2+xGap, Math.abs(xWidth/2-nx));
132                        cY = ImageMath.smoothStep(yWidth/2, yWidth/2+yGap, Math.abs(yWidth/2-ny));
133                } else {
134                        cX = cY = 0;
135                }
136
137                if (useImageColors) {
138                        lrgbX = lrgbY = rgb;
139                } else {
140                        lrgbX = rgbX;
141                        lrgbY = rgbY;
142                }
143                int v;
144                int ixc = ix % cols;
145                int iyr = iy % rows;
146                int m = matrix[iyr][ixc];
147                if (inX) {
148                        if (inY) {
149                                v = m == 1 ? lrgbX : lrgbY;
150                                v = ImageMath.mixColors(2 * (m == 1 ? dX : dY), v, 0xff000000);
151                        } else {
152                                if (shadeCrossings) {
153                                        if (m != matrix[(iy+1) % rows][ixc]) {
154                                                if (m == 0)
155                                                        cY = 1-cY;
156                                                cY *= 0.5f;
157                                                lrgbX = ImageMath.mixColors(cY, lrgbX, 0xff000000);
158                                        } else if (m == 0)
159                                                lrgbX = ImageMath.mixColors(0.5f, lrgbX, 0xff000000);
160                                }
161                                v = ImageMath.mixColors(2 * dX, lrgbX, 0xff000000);
162                        }
163                } else if (inY) {
164                        if (shadeCrossings) {
165                                if (m != matrix[iyr][(ix+1) % cols]) {
166                                        if (m == 1)
167                                                cX = 1-cX;
168                                        cX *= 0.5f;
169                                        lrgbY = ImageMath.mixColors(cX, lrgbY, 0xff000000);
170                                } else if (m == 1)
171                                        lrgbY = ImageMath.mixColors(0.5f, lrgbY, 0xff000000);
172                        }
173                        v = ImageMath.mixColors(2 * dY, lrgbY, 0xff000000);
174                } else
175                        v = 0x00000000;
176                return v;
177        }
178
179        public String toString() {
180                return "Texture/Weave...";
181        }
182
183}
184
185