/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Created on Jan 11, 2006 */ package net.sf.nmedit.nmutils.graphics; import java.awt.Color; import java.awt.Paint; import java.awt.PaintContext; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; public class RoundGradientPaint implements Paint { private Point2D mid, rad; private Color cinner, couter; public RoundGradientPaint(Ellipse2D ellipse, Color inner, Color outer) { this(ellipse.getCenterX(), ellipse.getCenterY(), ellipse.getCenterX(), ellipse.getCenterY(), inner, outer); } public RoundGradientPaint(double midx,double midy,double rad, Color inner,Color outer) { this(midx,midy,rad,rad,inner,outer); } public RoundGradientPaint(double midx,double midy,double radx,double rady, Color inner,Color outer) { this(new Point2D.Double(midx,midy),new Point2D.Double(radx,rady),inner,outer); } public RoundGradientPaint(Point2D mid, Point2D rad, Color inner,Color outer) { this.mid=mid; this.rad=rad; this.cinner=inner;this.couter=outer; } public void setInnerColor(Color color) { this.cinner = color; } public void setOuterColor(Color color) { this.couter = color; } public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) { Point2D transformedMid = xform.transform(mid, null); Point2D transformedRad = xform.deltaTransform(rad, null); return new RoundGradientPC(transformedMid, transformedRad); } public int getTransparency() { int a1 = cinner.getAlpha(); int a2 = couter.getAlpha(); return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT); } private class RoundGradientPC implements PaintContext { private Point2D mid, rad; public RoundGradientPC(Point2D mid, Point2D rad) { this.mid=mid; this.rad=rad; } public ColorModel getColorModel() { return ColorModel.getRGBdefault(); } public Raster getRaster(int x, int y, int w, int h) { WritableRaster raster = getColorModel().createCompatibleWritableRaster(w, h); // optimized float[] distx = new float[w]; float dx = (float) mid.getX()-x; for (int i = 0; i < w; i++) { distx[i] = dx-i; distx[i] = distx[i]*distx[i]; } float[] disty; float dy = (float) mid.getY()-y; if (w==h && dx==dy) { disty = distx; } else { disty = new float[h]; for (int i = 0; i < h; i++) { disty[i] = dy-i; disty[i] = disty[i]*disty[i]; } } // for loop int c1r=cinner.getRed(); int c1g=cinner.getGreen(); int c1b=cinner.getBlue(); int c1a=cinner.getAlpha(); int c2r=couter.getRed(); int c2g=couter.getGreen(); int c2b=couter.getBlue(); int c2a=couter.getAlpha(); int difr=c2r-c1r; int difg=c2g-c1g; int difb=c2b-c1b; int difa=c2a-c1a; float radius = (float) rad.distance(0,0); float distance; float ratio; int base; //int fixpoint = radius; int[] data = new int[w * h * 4]; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { distance = (float) Math.sqrt(distx[i]+disty[j]); ratio = Math.min(distance / radius, 1); base = (j * w + i) * 4; data[base + 0] = (int) (c1r + ratio*difr); data[base + 1] = (int) (c1g + ratio*difg); data[base + 2] = (int) (c1b + ratio*difb); data[base + 3] = (int) (c1a + ratio*difa); } } /* // working:: for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { double distance = mid.distance(x + i, y + j); double radius = rad.distance(0, 0); double ratio = distance / radius; if (ratio > 1.0) ratio = 1.0; int base = (j * w + i) * 4; data[base + 0] = (int) (c1r + ratio* (c2r - c1r)); data[base + 1] = (int) (c1g + ratio* (c2g - c1g)); data[base + 2] = (int) (c1b + ratio* (c2b - c1b)); data[base + 3] = (int) (c1a + ratio* (c2a - c1a)); } } */ raster.setPixels(0, 0, w, h, data); return raster; } public void dispose() { } } }