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