From 3330927bdd2fedcbc8745f99d3f40929f47fdd31 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Tue, 19 Jan 2010 18:51:06 -0800 Subject: [PATCH] ADT/Layoutlib: implement sweep gradient. Change-Id: I2d460decff82f5f64b0a5cfeaa68156aad4fb3e6 --- .../src/android/graphics/GradientShader.java | 92 ++++++++++--------- .../src/android/graphics/RadialGradient.java | 8 +- .../bridge/src/android/graphics/SweepGradient.java | 100 ++++++++++++++++++--- 3 files changed, 140 insertions(+), 60 deletions(-) diff --git a/tools/layoutlib/bridge/src/android/graphics/GradientShader.java b/tools/layoutlib/bridge/src/android/graphics/GradientShader.java index 40e5df2a8371..8c5a2a41b961 100644 --- a/tools/layoutlib/bridge/src/android/graphics/GradientShader.java +++ b/tools/layoutlib/bridge/src/android/graphics/GradientShader.java @@ -120,50 +120,58 @@ public abstract class GradientShader extends Shader { */ protected int getGradientColor(float pos) { if (pos < 0.f) { - switch (mTileMode) { - case CLAMP: - pos = 0.f; - break; - case REPEAT: - // remove the integer part to stay in the [0,1] range - // careful: this is a negative value, so use ceil instead of floor - pos = pos - (float)Math.ceil(pos); - break; - case MIRROR: - // get the integer and the decimal part - // careful: this is a negative value, so use ceil instead of floor - int intPart = (int)Math.ceil(pos); - pos = pos - intPart; - // 0 -> -1 : mirrored order - // -1 -> -2: normal order - // etc.. - // this means if the intpart is even we invert - if ((intPart % 2) == 0) { - pos = 1.f - pos; - } - break; + if (mTileMode != null) { + switch (mTileMode) { + case CLAMP: + pos = 0.f; + break; + case REPEAT: + // remove the integer part to stay in the [0,1] range + // careful: this is a negative value, so use ceil instead of floor + pos = pos - (float)Math.ceil(pos); + break; + case MIRROR: + // get the integer and the decimal part + // careful: this is a negative value, so use ceil instead of floor + int intPart = (int)Math.ceil(pos); + pos = pos - intPart; + // 0 -> -1 : mirrored order + // -1 -> -2: normal order + // etc.. + // this means if the intpart is even we invert + if ((intPart % 2) == 0) { + pos = 1.f - pos; + } + break; + } + } else { + pos = 0.0f; } } else if (pos > 1f) { - switch (mTileMode) { - case CLAMP: - pos = 1.f; - break; - case REPEAT: - // remove the integer part to stay in the [0,1] range - pos = pos - (float)Math.floor(pos); - break; - case MIRROR: - // get the integer and the decimal part - int intPart = (int)Math.floor(pos); - pos = pos - intPart; - // 0 -> 1 : normal order - // 1 -> 2: mirrored - // etc.. - // this means if the intpart is odd we invert - if ((intPart % 2) == 1) { - pos = 1.f - pos; - } - break; + if (mTileMode != null) { + switch (mTileMode) { + case CLAMP: + pos = 1.f; + break; + case REPEAT: + // remove the integer part to stay in the [0,1] range + pos = pos - (float)Math.floor(pos); + break; + case MIRROR: + // get the integer and the decimal part + int intPart = (int)Math.floor(pos); + pos = pos - intPart; + // 0 -> 1 : normal order + // 1 -> 2: mirrored + // etc.. + // this means if the intpart is odd we invert + if ((intPart % 2) == 1) { + pos = 1.f - pos; + } + break; + } + } else { + pos = 1.0f; } } diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java index db8dff2f4b53..4409a800e652 100644 --- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java +++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java @@ -78,11 +78,11 @@ public class RadialGradient extends GradientShader { } public java.awt.PaintContext createContext( - java.awt.image.ColorModel colorModel, - java.awt.Rectangle deviceBounds, - java.awt.geom.Rectangle2D userBounds, + java.awt.image.ColorModel colorModel, + java.awt.Rectangle deviceBounds, + java.awt.geom.Rectangle2D userBounds, java.awt.geom.AffineTransform xform, - java.awt.RenderingHints hints) { + java.awt.RenderingHints hints) { precomputeGradientColors(); return new RadialGradientPaintContext(colorModel); } diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java index 21d8244c0992..87036ed8f885 100644 --- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java +++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java @@ -16,9 +16,9 @@ package android.graphics; -import java.awt.Paint; +public class SweepGradient extends GradientShader { -public class SweepGradient extends Shader { + private SweepGradientPaint mPaint; /** * A subclass of Shader that draws a sweep gradient around a center point. @@ -36,15 +36,9 @@ public class SweepGradient extends Shader { */ public SweepGradient(float cx, float cy, int colors[], float positions[]) { - if (colors.length < 2) { - throw new IllegalArgumentException("needs >= 2 number of colors"); - } - if (positions != null && colors.length != positions.length) { - throw new IllegalArgumentException( - "color and position arrays must be of equal length"); - } + super(colors, positions); - // FIXME Implement shader + mPaint = new SweepGradientPaint(cx, cy, mColors, mPositions); } /** @@ -56,13 +50,91 @@ public class SweepGradient extends Shader { * @param color1 The color to use at the end of the sweep */ public SweepGradient(float cx, float cy, int color0, int color1) { - // FIXME Implement shader + this(cx, cy, new int[] { color0, color1}, null /*positions*/); } @Override - Paint getJavaPaint() { - // TODO Auto-generated method stub - return null; + java.awt.Paint getJavaPaint() { + return mPaint; } + + private static class SweepGradientPaint extends GradientPaint { + + private final float mCx; + private final float mCy; + + public SweepGradientPaint(float cx, float cy, int[] colors, float[] positions) { + super(colors, positions, null /*tileMode*/); + mCx = cx; + mCy = cy; + } + + public java.awt.PaintContext createContext( + java.awt.image.ColorModel colorModel, + java.awt.Rectangle deviceBounds, + java.awt.geom.Rectangle2D userBounds, + java.awt.geom.AffineTransform xform, + java.awt.RenderingHints hints) { + precomputeGradientColors(); + return new SweepGradientPaintContext(colorModel); + } + + private class SweepGradientPaintContext implements java.awt.PaintContext { + + private final java.awt.image.ColorModel mColorModel; + + public SweepGradientPaintContext(java.awt.image.ColorModel colorModel) { + mColorModel = colorModel; + } + + public void dispose() { + } + + public java.awt.image.ColorModel getColorModel() { + return mColorModel; + } + + public java.awt.image.Raster getRaster(int x, int y, int w, int h) { + java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h, + java.awt.image.BufferedImage.TYPE_INT_ARGB); + + int[] data = new int[w*h]; + + // compute angle from each point to the center, and figure out the distance from + // it. + int index = 0; + for (int iy = 0 ; iy < h ; iy++) { + for (int ix = 0 ; ix < w ; ix++) { + float dx = x + ix - mCx; + float dy = y + iy - mCy; + float angle; + if (dx == 0) { + angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2); + } else if (dy == 0) { + angle = (float) (dx < 0 ? Math.PI : 0); + } else { + angle = (float) Math.atan(dy / dx); + if (dx > 0) { + if (dy < 0) { + angle += Math.PI * 2; + } + } else { + angle += Math.PI; + } + } + + // convert to 0-1. value and get color + data[index++] = getGradientColor((float) (angle / (2 * Math.PI))); + } + } + + image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/); + + return image.getRaster(); + } + + } + } + } -- 2.11.0