FileDocCategorySizeDatePackage
ShadowPainter.javaAPI DocAndroid 5.1 API17350Thu Mar 12 22:22:44 GMT 2015android.view

ShadowPainter

public class ShadowPainter extends Object

Fields Summary
public static final int
SHADOW_SIZE
The width and height of the drop shadow painted by {@link #drawRectangleShadow(Graphics2D, int, int, int, int)}
public static final int
SMALL_SHADOW_SIZE
The width and height of the drop shadow painted by {@link #drawSmallRectangleShadow(Graphics2D, int, int, int, int)}
private static final Image
ShadowBottom
private static final Image
ShadowBottomLeft
private static final Image
ShadowBottomRight
private static final Image
ShadowRight
private static final Image
ShadowTopRight
private static final Image
ShadowTopLeft
private static final Image
ShadowLeft
private static final Image
Shadow2Bottom
private static final Image
Shadow2BottomLeft
private static final Image
Shadow2BottomRight
private static final Image
Shadow2Right
private static final Image
Shadow2TopRight
private static final Image
Shadow2TopLeft
private static final Image
Shadow2Left
Constructors Summary
Methods Summary
public static java.awt.image.BufferedImagecreateDropShadow(java.awt.image.BufferedImage source, int shadowSize)
Adds a drop shadow to a semi-transparent image (of an arbitrary shape) and returns it as a new image. This method attempts to mimic the same visual characteristics as the rectangular shadow painting methods in this class, {@link #createRectangularDropShadow(java.awt.image.BufferedImage)} and {@link #createSmallRectangularDropShadow(java.awt.image.BufferedImage)}.

param
source the source image
param
shadowSize the size of the shadow, normally {@link #SHADOW_SIZE or {@link #SMALL_SHADOW_SIZE}}
return
a new image with the shadow painted in

        shadowSize /= 2; // make shadow size have the same meaning as in the other shadow paint methods in this class

        return createDropShadow(source, shadowSize, 0.7f, 0);
    
public static java.awt.image.BufferedImagecreateDropShadow(java.awt.image.BufferedImage source, int shadowSize, float shadowOpacity, int shadowRgb)
Creates a drop shadow of a given image and returns a new image which shows the input image on top of its drop shadow.

NOTE: If the shape is rectangular and opaque, consider using {@link #drawRectangleShadow(Graphics2D, int, int, int, int)} instead.

param
source the source image to be shadowed
param
shadowSize the size of the shadow in pixels
param
shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque
param
shadowRgb the RGB int to use for the shadow color
return
a new image with the source image on top of its shadow


        // This code is based on
        //      http://www.jroller.com/gfx/entry/non_rectangular_shadow

        BufferedImage image;
        int width = source.getWidth();
        int height = source.getHeight();
        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE,
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2 = image.createGraphics();
        g2.drawImage(image, shadowSize, shadowSize, null);

        int dstWidth = image.getWidth();
        int dstHeight = image.getHeight();

        int left = (shadowSize - 1) >> 1;
        int right = shadowSize - left;
        int xStart = left;
        int xStop = dstWidth - right;
        int yStart = left;
        int yStop = dstHeight - right;

        shadowRgb &= 0x00FFFFFF;

        int[] aHistory = new int[shadowSize];
        int historyIdx;

        int aSum;

        int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        int lastPixelOffset = right * dstWidth;
        float sumDivider = shadowOpacity / shadowSize;

        // horizontal pass
        for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
            aSum = 0;
            historyIdx = 0;
            for (int x = 0; x < shadowSize; x++, bufferOffset++) {
                int a = dataBuffer[bufferOffset] >>> 24;
                aHistory[x] = a;
                aSum += a;
            }

            bufferOffset -= right;

            for (int x = xStart; x < xStop; x++, bufferOffset++) {
                int a = (int) (aSum * sumDivider);
                dataBuffer[bufferOffset] = a << 24 | shadowRgb;

                // subtract the oldest pixel from the sum
                aSum -= aHistory[historyIdx];

                // get the latest pixel
                a = dataBuffer[bufferOffset + right] >>> 24;
                aHistory[historyIdx] = a;
                aSum += a;

                if (++historyIdx >= shadowSize) {
                    historyIdx -= shadowSize;
                }
            }
        }
        // vertical pass
        for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
            aSum = 0;
            historyIdx = 0;
            for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
                int a = dataBuffer[bufferOffset] >>> 24;
                aHistory[y] = a;
                aSum += a;
            }

            bufferOffset -= lastPixelOffset;

            for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
                int a = (int) (aSum * sumDivider);
                dataBuffer[bufferOffset] = a << 24 | shadowRgb;

                // subtract the oldest pixel from the sum
                aSum -= aHistory[historyIdx];

                // get the latest pixel
                a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
                aHistory[historyIdx] = a;
                aSum += a;

                if (++historyIdx >= shadowSize) {
                    historyIdx -= shadowSize;
                }
            }
        }

        g2.drawImage(source, null, 0, 0);
        g2.dispose();

        return image;
    
public static java.awt.image.BufferedImagecreateRectangularDropShadow(java.awt.image.BufferedImage source)
Draws a rectangular drop shadow (of size {@link #SHADOW_SIZE} by {@link #SHADOW_SIZE} around the given source and returns a new image with both combined

param
source the source image
return
the source image with a drop shadow on the bottom and right

        int type = source.getType();
        if (type == BufferedImage.TYPE_CUSTOM) {
            type = BufferedImage.TYPE_INT_ARGB;
        }

        int width = source.getWidth();
        int height = source.getHeight();
        BufferedImage image;
        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE, type);
        Graphics2D g = image.createGraphics();
        g.drawImage(source, 0, 0, null);
        drawRectangleShadow(image, 0, 0, width, height);
        g.dispose();

        return image;
    
public static java.awt.image.BufferedImagecreateSmallRectangularDropShadow(java.awt.image.BufferedImage source)
Draws a small rectangular drop shadow (of size {@link #SMALL_SHADOW_SIZE} by {@link #SMALL_SHADOW_SIZE} around the given source and returns a new image with both combined

param
source the source image
return
the source image with a drop shadow on the bottom and right

        int type = source.getType();
        if (type == BufferedImage.TYPE_CUSTOM) {
            type = BufferedImage.TYPE_INT_ARGB;
        }

        int width = source.getWidth();
        int height = source.getHeight();

        BufferedImage image;
        image = new BufferedImage(width + SMALL_SHADOW_SIZE, height + SMALL_SHADOW_SIZE, type);

        Graphics2D g = image.createGraphics();
        g.drawImage(source, 0, 0, null);
        drawSmallRectangleShadow(image, 0, 0, width, height);
        g.dispose();

        return image;
    
public static voiddrawRectangleShadow(java.awt.image.BufferedImage image, int x, int y, int width, int height)
Draws a drop shadow for the given rectangle into the given context. It will not draw anything if the rectangle is smaller than a minimum determined by the assets used to draw the shadow graphics. The size of the shadow is {@link #SHADOW_SIZE}.

param
image the image to draw the shadow into
param
x the left coordinate of the left hand side of the rectangle
param
y the top coordinate of the top of the rectangle
param
width the width of the rectangle
param
height the height of the rectangle

        Graphics2D gc = image.createGraphics();
        try {
            drawRectangleShadow(gc, x, y, width, height);
        } finally {
            gc.dispose();
        }
    
public static voiddrawRectangleShadow(java.awt.Graphics2D gc, int x, int y, int width, int height)
Draws a drop shadow for the given rectangle into the given context. It will not draw anything if the rectangle is smaller than a minimum determined by the assets used to draw the shadow graphics.

param
gc the graphics context to draw into
param
x the left coordinate of the left hand side of the rectangle
param
y the top coordinate of the top of the rectangle
param
width the width of the rectangle
param
height the height of the rectangle

 // DO NOT EDIT. Corresponds to bitmap graphics

                                                                                          
                 
        assert ShadowBottomLeft != null;
        assert ShadowBottomRight.getWidth(null) == SHADOW_SIZE;
        assert ShadowBottomRight.getHeight(null) == SHADOW_SIZE;

        int blWidth = ShadowBottomLeft.getWidth(null);
        int trHeight = ShadowTopRight.getHeight(null);
        if (width < blWidth) {
            return;
        }
        if (height < trHeight) {
            return;
        }

        gc.drawImage(ShadowBottomLeft, x - ShadowBottomLeft.getWidth(null), y + height, null);
        gc.drawImage(ShadowBottomRight, x + width, y + height, null);
        gc.drawImage(ShadowTopRight, x + width, y, null);
        gc.drawImage(ShadowTopLeft, x - ShadowTopLeft.getWidth(null), y, null);
        gc.drawImage(ShadowBottom,
                x, y + height, x + width, y + height + ShadowBottom.getHeight(null),
                0, 0, ShadowBottom.getWidth(null), ShadowBottom.getHeight(null), null);
        gc.drawImage(ShadowRight,
                x + width, y + ShadowTopRight.getHeight(null), x + width + ShadowRight.getWidth(null), y + height,
                0, 0, ShadowRight.getWidth(null), ShadowRight.getHeight(null), null);
        gc.drawImage(ShadowLeft,
                x - ShadowLeft.getWidth(null), y + ShadowTopLeft.getHeight(null), x, y + height,
                0, 0, ShadowLeft.getWidth(null), ShadowLeft.getHeight(null), null);
    
public static voiddrawSmallRectangleShadow(java.awt.image.BufferedImage image, int x, int y, int width, int height)
Draws a small drop shadow for the given rectangle into the given context. It will not draw anything if the rectangle is smaller than a minimum determined by the assets used to draw the shadow graphics. The size of the shadow is {@link #SMALL_SHADOW_SIZE}.

param
image the image to draw the shadow into
param
x the left coordinate of the left hand side of the rectangle
param
y the top coordinate of the top of the rectangle
param
width the width of the rectangle
param
height the height of the rectangle

        Graphics2D gc = image.createGraphics();
        try {
            drawSmallRectangleShadow(gc, x, y, width, height);
        } finally {
            gc.dispose();
        }
    
public static voiddrawSmallRectangleShadow(java.awt.Graphics2D gc, int x, int y, int width, int height)
Draws a small drop shadow for the given rectangle into the given context. It will not draw anything if the rectangle is smaller than a minimum determined by the assets used to draw the shadow graphics.

param
gc the graphics context to draw into
param
x the left coordinate of the left hand side of the rectangle
param
y the top coordinate of the top of the rectangle
param
width the width of the rectangle
param
height the height of the rectangle

        assert Shadow2BottomLeft != null;
        assert Shadow2TopRight != null;
        assert Shadow2BottomRight.getWidth(null) == SMALL_SHADOW_SIZE;
        assert Shadow2BottomRight.getHeight(null) == SMALL_SHADOW_SIZE;

        int blWidth = Shadow2BottomLeft.getWidth(null);
        int trHeight = Shadow2TopRight.getHeight(null);
        if (width < blWidth) {
            return;
        }
        if (height < trHeight) {
            return;
        }

        gc.drawImage(Shadow2BottomLeft, x - Shadow2BottomLeft.getWidth(null), y + height, null);
        gc.drawImage(Shadow2BottomRight, x + width, y + height, null);
        gc.drawImage(Shadow2TopRight, x + width, y, null);
        gc.drawImage(Shadow2TopLeft, x - Shadow2TopLeft.getWidth(null), y, null);
        gc.drawImage(Shadow2Bottom,
                x, y + height, x + width, y + height + Shadow2Bottom.getHeight(null),
                0, 0, Shadow2Bottom.getWidth(null), Shadow2Bottom.getHeight(null), null);
        gc.drawImage(Shadow2Right,
                x + width, y + Shadow2TopRight.getHeight(null), x + width + Shadow2Right.getWidth(null), y + height,
                0, 0, Shadow2Right.getWidth(null), Shadow2Right.getHeight(null), null);
        gc.drawImage(Shadow2Left,
                x - Shadow2Left.getWidth(null), y + Shadow2TopLeft.getHeight(null), x, y + height,
                0, 0, Shadow2Left.getWidth(null), Shadow2Left.getHeight(null), null);
    
private static java.awt.ImageloadIcon(java.lang.String name)

        InputStream inputStream = ShadowPainter.class.getResourceAsStream(name);
        if (inputStream == null) {
            throw new RuntimeException("Unable to load image for shadow: " + name);
        }
        try {
            return ImageIO.read(inputStream);
        } catch (IOException e) {
            throw new RuntimeException("Unable to load image for shadow:" + name, e);
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                // ignore.
            }
        }