1 7 8 package java.awt; 9 10 import java.awt.image.Raster ; 11 import java.awt.image.WritableRaster ; 12 import sun.awt.image.IntegerComponentRaster; 13 import java.awt.image.ColorModel ; 14 import java.awt.image.DirectColorModel ; 15 import java.awt.geom.Point2D ; 16 import java.awt.geom.AffineTransform ; 17 import java.awt.geom.NoninvertibleTransformException ; 18 import java.lang.ref.WeakReference ; 19 20 class GradientPaintContext implements PaintContext { 21 static ColorModel xrgbmodel = 22 new DirectColorModel (24, 0x00ff0000, 0x0000ff00, 0x000000ff); 23 static ColorModel xbgrmodel = 24 new DirectColorModel (24, 0x000000ff, 0x0000ff00, 0x00ff0000); 25 26 static ColorModel cachedModel; 27 static WeakReference cached; 28 29 static synchronized Raster getCachedRaster(ColorModel cm, int w, int h) { 30 if (cm == cachedModel) { 31 if (cached != null) { 32 Raster ras = (Raster ) cached.get(); 33 if (ras != null && 34 ras.getWidth() >= w && 35 ras.getHeight() >= h) 36 { 37 cached = null; 38 return ras; 39 } 40 } 41 } 42 return cm.createCompatibleWritableRaster(w, h); 43 } 44 45 static synchronized void putCachedRaster(ColorModel cm, Raster ras) { 46 if (cached != null) { 47 Raster cras = (Raster ) cached.get(); 48 if (cras != null) { 49 int cw = cras.getWidth(); 50 int ch = cras.getHeight(); 51 int iw = ras.getWidth(); 52 int ih = ras.getHeight(); 53 if (cw >= iw && ch >= ih) { 54 return; 55 } 56 if (cw * ch >= iw * ih) { 57 return; 58 } 59 } 60 } 61 cachedModel = cm; 62 cached = new WeakReference (ras); 63 } 64 65 double x1; 66 double y1; 67 double dx; 68 double dy; 69 boolean cyclic; 70 int interp[]; 71 Raster saved; 72 ColorModel model; 73 74 public GradientPaintContext(ColorModel cm, 75 Point2D p1, Point2D p2, AffineTransform xform, 76 Color c1, Color c2, boolean cyclic) { 77 Point2D xvec = new Point2D.Double (1, 0); 80 Point2D yvec = new Point2D.Double (0, 1); 81 try { 82 AffineTransform inverse = xform.createInverse(); 83 inverse.deltaTransform(xvec, xvec); 84 inverse.deltaTransform(yvec, yvec); 85 } catch (NoninvertibleTransformException e) { 86 xvec.setLocation(0, 0); 87 yvec.setLocation(0, 0); 88 } 89 90 double udx = p2.getX() - p1.getX(); 94 double udy = p2.getY() - p1.getY(); 95 double ulenSq = udx * udx + udy * udy; 96 97 if (ulenSq <= Double.MIN_VALUE) { 98 dx = 0; 99 dy = 0; 100 } else { 101 dx = (xvec.getX() * udx + xvec.getY() * udy) / ulenSq; 117 dy = (yvec.getX() * udx + yvec.getY() * udy) / ulenSq; 118 119 if (cyclic) { 120 dx = dx % 1.0; 121 dy = dy % 1.0; 122 } else { 123 if (dx < 0) { 125 Point2D p = p1; p1 = p2; p2 = p; 131 Color c = c1; c1 = c2; c2 = c; 132 dx = -dx; 133 dy = -dy; 134 } 135 } 136 } 137 138 Point2D dp1 = xform.transform(p1, null); 139 this.x1 = dp1.getX(); 140 this.y1 = dp1.getY(); 141 142 this.cyclic = cyclic; 143 int rgb1 = c1.getRGB(); 144 int rgb2 = c2.getRGB(); 145 int a1 = (rgb1 >> 24) & 0xff; 146 int r1 = (rgb1 >> 16) & 0xff; 147 int g1 = (rgb1 >> 8) & 0xff; 148 int b1 = (rgb1 ) & 0xff; 149 int da = ((rgb2 >> 24) & 0xff) - a1; 150 int dr = ((rgb2 >> 16) & 0xff) - r1; 151 int dg = ((rgb2 >> 8) & 0xff) - g1; 152 int db = ((rgb2 ) & 0xff) - b1; 153 if (a1 == 0xff && da == 0) { 154 model = xrgbmodel; 155 if (cm instanceof DirectColorModel ) { 156 DirectColorModel dcm = (DirectColorModel ) cm; 157 int tmp = dcm.getAlphaMask(); 158 if ((tmp == 0 || tmp == 0xff) && 159 dcm.getRedMask() == 0xff && 160 dcm.getGreenMask() == 0xff00 && 161 dcm.getBlueMask() == 0xff0000) 162 { 163 model = xbgrmodel; 164 tmp = r1; r1 = b1; b1 = tmp; 165 tmp = dr; dr = db; db = tmp; 166 } 167 } 168 } else { 169 model = ColorModel.getRGBdefault(); 170 } 171 interp = new int[cyclic ? 513 : 257]; 172 for (int i = 0; i <= 256; i++) { 173 float rel = i / 256.0f; 174 int rgb = 175 (((int) (a1 + da * rel)) << 24) | 176 (((int) (r1 + dr * rel)) << 16) | 177 (((int) (g1 + dg * rel)) << 8) | 178 (((int) (b1 + db * rel)) ); 179 interp[i] = rgb; 180 if (cyclic) { 181 interp[512 - i] = rgb; 182 } 183 } 184 } 185 186 189 public void dispose() { 190 if (saved != null) { 191 putCachedRaster(model, saved); 192 saved = null; 193 } 194 } 195 196 199 public ColorModel getColorModel() { 200 return model; 201 } 202 203 209 public Raster getRaster(int x, int y, int w, int h) { 210 double rowrel = (x - x1) * dx + (y - y1) * dy; 211 212 Raster rast = saved; 213 if (rast == null || rast.getWidth() < w || rast.getHeight() < h) { 214 rast = getCachedRaster(model, w, h); 215 saved = rast; 216 } 217 IntegerComponentRaster irast = (IntegerComponentRaster) rast; 218 int off = irast.getDataOffset(0); 219 int adjust = irast.getScanlineStride() - w; 220 int[] pixels = irast.getDataStorage(); 221 222 if (cyclic) { 223 cycleFillRaster(pixels, off, adjust, w, h, rowrel, dx, dy); 224 } else { 225 clipFillRaster(pixels, off, adjust, w, h, rowrel, dx, dy); 226 } 227 228 return rast; 229 } 230 231 void cycleFillRaster(int[] pixels, int off, int adjust, int w, int h, 232 double rowrel, double dx, double dy) { 233 rowrel = rowrel % 2.0; 234 int irowrel = ((int) (rowrel * (1 << 30))) << 1; 235 int idx = (int) (-dx * (1 << 31)); 236 int idy = (int) (-dy * (1 << 31)); 237 while (--h >= 0) { 238 int icolrel = irowrel; 239 for (int j = w; j > 0; j--) { 240 pixels[off++] = interp[icolrel >>> 23]; 241 icolrel += idx; 242 } 243 244 off += adjust; 245 irowrel += idy; 246 } 247 } 248 249 void clipFillRaster(int[] pixels, int off, int adjust, int w, int h, 250 double rowrel, double dx, double dy) { 251 while (--h >= 0) { 252 double colrel = rowrel; 253 int j = w; 254 if (colrel <= 0.0) { 255 int rgb = interp[0]; 256 do { 257 pixels[off++] = rgb; 258 colrel += dx; 259 } while (--j > 0 && colrel <= 0.0); 260 } 261 while (colrel < 1.0 && --j >= 0) { 262 pixels[off++] = interp[(int) (colrel * 256)]; 263 colrel += dx; 264 } 265 if (j > 0) { 266 int rgb = interp[256]; 267 do { 268 pixels[off++] = rgb; 269 } while (--j > 0); 270 } 271 272 off += adjust; 273 rowrel += dy; 274 } 275 } 276 } 277 | Popular Tags |