alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.netbeans.swing.plaf.aqua;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;

/**
 * A gradient paint context which paints rounded borders.
 *
 * @author Tim Boudreau
 */
public class ShapeGradientContext implements PaintContext {
    protected Color shadowColor, bgColor;
    protected Rectangle r;
    int cornerRadius = 6;
    public ShapeGradientContext(Rectangle r, Color c1, Color c2) {
        shadowColor = c1;
        bgColor = c2;
        this.r = r;
        
        r.height -= cornerRadius * 2;
        r.width -= cornerRadius * 4;
        r.x += (cornerRadius * 2) + 1;
        r.y += cornerRadius;
    }
    
    public void dispose() {}
    
    public ColorModel getColorModel() { return ColorModel.getRGBdefault(); }
    
    int shadowWidth = 21;
    
    private WritableRaster raster = null;
    int[] last = new int[] {-1,-1,-1,-1};
    
    public Raster getRaster(int x, int y, int w, int h) {
        if (this.raster != null && x == last[0] && y == last[1] && w == last[2] &&
            h == last[3]) {
            return raster;
        }
        
        last[0] = x; last[1] = y; last[2] = w; last[3] = h;
        raster =
            getColorModel().createCompatibleWritableRaster(w, h);
        
        //XXX We don't need to allocate all this memory, we're only drawing
        //into a small strip down the side 
        
//        int[] data = new int[w * h * 4];
        
        for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i++) {
                
                //OPTIMIZATION: Skip interior pixels far from the edges
                if (j < r.y + r.height - (shadowWidth + cornerRadius)) {
                    int rightStart  = w - (r.x + r.width + shadowWidth + cornerRadius);
                    if (i > (shadowWidth + cornerRadius) && w < rightStart) {
                        //Skip ahead to the right edge if we're not painting
                        //the bottom
                        i = rightStart;
                    }
                }
                
                double ratio = 1;
                Point2D.Double nearest = POINT;
                nearest.setLocation(i > r.x + r.width ? r.x + r.width : i < r.x ? r.x : i,
                    Math.min (j, y+r.y+r.height)); 
                
                //Calculate the distance to the nearest point on the nearest
                //edge
                double dist = nearest.distance (x + i, y + j) + 1;
                
                
                //Multiply in the corner radius as needed to get rounded
                //looking shadows
                dist *= dist / ((shadowWidth - x) + cornerRadius);
                
                //Fade the shadow at the top so it doesn't have a sharp upper 
                //edge
                if (j <= (cornerRadius * 2)) {
                    double factor = (double) (cornerRadius * 2) / (double) j;
                    dist *= factor;
                }

                //Get the ratio between the colors
                ratio = dist / (shadowWidth - x);

                //Normalize to 1.0 or strange things happen
                if (ratio > 1.0)
                    ratio = 1.0;
                
                //Index of pixel
//                int base = (j * w + i) * 4;
                int base = 0;
                
                data[base + 0] = (int)(shadowColor.getRed() + ratio *
                (bgColor.getRed() - shadowColor.getRed()));
                data[base + 1] = (int)(shadowColor.getGreen() + ratio *
                (bgColor.getGreen() - shadowColor.getGreen()));
                data[base + 2] = (int)(shadowColor.getBlue() + ratio *
                (bgColor.getBlue() - shadowColor.getBlue()));
                data[base + 3] = (int)(shadowColor.getAlpha() + ratio *
                (bgColor.getAlpha() - shadowColor.getAlpha()));
                
                raster.setPixels (i, j, 1, 1, data);
            }
        }
//        raster.setPixels(0, 0, w, h, data);
         
        
        return raster;
    }
    private static int[] data = new int[4];
    private static Point2D.Double POINT = new Point2D.Double();
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.