/* * This file is part of WebLookAndFeel library. * * WebLookAndFeel library 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 3 of the License, or * (at your option) any later version. * * WebLookAndFeel library 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 WebLookAndFeel library. If not, see <http://www.gnu.org/licenses/>. */ package com.alee.laf.colorchooser; import com.alee.api.annotations.NotNull; import com.alee.utils.ColorUtils; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.util.HashMap; import java.util.Map; /** * @author Mikle Garin */ public class PaletteColorChooserPaint implements Paint { private Color cornerColor; private boolean webSafe = false; private ColorModel model = ColorModel.getRGBdefault (); private int x; private int y; private int width; private int height; public PaletteColorChooserPaint ( final int x, final int y, final int width, final int height, @NotNull final Color cornerColor ) { this.x = x; this.y = y; this.width = width; this.height = height; this.cornerColor = cornerColor; } @Override public PaintContext createContext ( final ColorModel cm, final Rectangle deviceBounds, final Rectangle2D userBounds, final AffineTransform xform, final RenderingHints hints ) { return new PaintContext () { private Map<Rectangle, WritableRaster> rastersCache = new HashMap<Rectangle, WritableRaster> (); @Override public void dispose () { rastersCache.clear (); } @Override public ColorModel getColorModel () { return model; } @Override public Raster getRaster ( int x, int y, final int w, final int h ) { final Rectangle r = new Rectangle ( x, y, w, h ); if ( rastersCache.containsKey ( r ) ) { return rastersCache.get ( r ); } else { final WritableRaster raster = model.createCompatibleWritableRaster ( w, h ); x -= Math.round ( xform.getTranslateX () ); y -= Math.round ( xform.getTranslateY () ); final int[] data = new int[ w * h * 4 ]; for ( int j = 0; j < h; j++ ) { for ( int i = 0; i < w; i++ ) { final int base = ( j * w + i ) * 4; data[ base ] = getRed ( x + i, y + j ); data[ base + 1 ] = getGreen ( x + i, y + j ); data[ base + 2 ] = getBlue ( x + i, y + j ); data[ base + 3 ] = 255; } } raster.setPixels ( 0, 0, w, h, data ); rastersCache.put ( r, raster ); return raster; } } }; } public Color getColor ( int xCoord, int yCoord ) { if ( xCoord < x ) { xCoord = x; } else if ( xCoord > x + 256 ) { xCoord = x + 256; } if ( yCoord < y ) { yCoord = y; } else if ( yCoord > y + 256 ) { yCoord = y + 256; } return new Color ( getRed ( xCoord, yCoord ), getGreen ( xCoord, yCoord ), getBlue ( xCoord, yCoord ) ); } private int getRed ( final int xCoord, final int yCoord ) { int red = 255 - ( 255 - cornerColor.getRed () ) * ( xCoord - x ) / width; red = red - ( red ) * ( yCoord - y ) / height; return getWebSafe ( red ); } private int getGreen ( final int xCoord, final int yCoord ) { int green = 255 - ( 255 - cornerColor.getGreen () ) * ( xCoord - x ) / width; green = green - ( green ) * ( yCoord - y ) / height; return getWebSafe ( green ); } private int getBlue ( final int xCoord, final int yCoord ) { int blue = 255 - ( 255 - cornerColor.getBlue () ) * ( xCoord - x ) / width; blue = blue - ( blue ) * ( yCoord - y ) / height; return getWebSafe ( blue ); } private int getWebSafe ( int color ) { if ( webSafe ) { color = ColorUtils.webSafe ( color ); } if ( color < 0 ) { color = 0; } else if ( color > 255 ) { color = 255; } return color; } @Override public int getTransparency () { return OPAQUE; } public Color getCornerColor () { return cornerColor; } public boolean isWebSafe () { return webSafe; } public void setWebSafe ( final boolean webSafe ) { this.webSafe = webSafe; } }