summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2010-12-14 14:40:41 -0800
committerXavier Ducrohet <xav@android.com>2010-12-14 14:49:55 -0800
commitd9c64369cf9be6568af2d79c35fb470cc261730d (patch)
tree87e517f31538bdf425e660032784ee98e9b38c52 /tools
parentf1416e4dffb0874f163febfa12f2648eac0c3a77 (diff)
downloadframeworks_base-d9c64369cf9be6568af2d79c35fb470cc261730d.zip
frameworks_base-d9c64369cf9be6568af2d79c35fb470cc261730d.tar.gz
frameworks_base-d9c64369cf9be6568af2d79c35fb470cc261730d.tar.bz2
LayoutLib: Fix gradient rendering.
- fully support canvas transform - fully support shader local transform - fix repeat/mirror issue in the negative values. Change-Id: Ib2aa7ade1c2702da4364cbda9a5a3ae72c1d3174
Diffstat (limited to 'tools')
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java21
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java86
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java52
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java17
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java52
6 files changed, 166 insertions, 64 deletions
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
index 042d557..bc4ccd2 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
@@ -119,20 +119,23 @@ public abstract class Gradient_Delegate extends Shader_Delegate {
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);
+ // remove the integer part to stay in the [0,1] range.
+ // we also need to invert the value from [-1,0] to [0, 1]
+ pos = pos - (float)Math.floor(pos);
break;
case MIRROR:
+ // this is the same as the positive side, just make the value positive
+ // first.
+ pos = Math.abs(pos);
+
// 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);
+ int intPart = (int)Math.floor(pos);
pos = pos - intPart;
- // 0 -> -1 : mirrored order
- // -1 -> -2: normal order
+ // 0 -> 1 : normal order
+ // 1 -> 2: mirrored
// etc..
- // this means if the intpart is even we invert
- if ((intPart % 2) == 0) {
+ // this means if the intpart is odd we invert
+ if ((intPart % 2) == 1) {
pos = 1.f - pos;
}
break;
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index 7573dc1..862b4544 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -16,11 +16,14 @@
package android.graphics;
+import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Shader.TileMode;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
/**
* Delegate implementing the native methods of android.graphics.LinearGradient
@@ -115,7 +118,7 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
* {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
* modes.
*/
- private static class LinearGradientPaint extends GradientPaint {
+ private class LinearGradientPaint extends GradientPaint {
private final float mX0;
private final float mY0;
@@ -126,11 +129,11 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
float positions[], TileMode tile) {
super(colors, positions, tile);
- mX0 = x0;
- mY0 = y0;
- mDx = x1 - x0;
- mDy = y1 - y0;
- mDSize2 = mDx * mDx + mDy * mDy;
+ mX0 = x0;
+ mY0 = y0;
+ mDx = x1 - x0;
+ mDy = y1 - y0;
+ mDSize2 = mDx * mDx + mDy * mDy;
}
public java.awt.PaintContext createContext(
@@ -140,16 +143,37 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
java.awt.geom.AffineTransform xform,
java.awt.RenderingHints hints) {
precomputeGradientColors();
- return new LinearGradientPaintContext(colorModel);
+
+ AffineTransform canvasMatrix;
+ try {
+ canvasMatrix = xform.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
+ canvasMatrix = new AffineTransform();
+ }
+
+ AffineTransform localMatrix = getLocalMatrix();
+ try {
+ localMatrix = localMatrix.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
+ localMatrix = new AffineTransform();
+ }
+
+ return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
}
private class LinearGradientPaintContext implements java.awt.PaintContext {
+ private final AffineTransform mCanvasMatrix;
+ private final AffineTransform mLocalMatrix;
private final java.awt.image.ColorModel mColorModel;
- public LinearGradientPaintContext(java.awt.image.ColorModel colorModel) {
+ public LinearGradientPaintContext(AffineTransform canvasMatrix,
+ AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+ mCanvasMatrix = canvasMatrix;
+ mLocalMatrix = localMatrix;
mColorModel = colorModel;
- // FIXME: so far all this is always the same rect gotten in getRaster with an identity matrix?
}
public void dispose() {
@@ -165,31 +189,22 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
int[] data = new int[w*h];
- if (mDx == 0) { // vertical gradient
- // compute first column and copy to all other columns
- int index = 0;
- for (int iy = 0 ; iy < h ; iy++) {
- int color = getColor(iy + y, mY0, mDy);
- for (int ix = 0 ; ix < w ; ix++) {
- data[index++] = color;
- }
- }
- } else if (mDy == 0) { // horizontal
- // compute first line in a tmp array and copy to all lines
- int[] line = new int[w];
+ int index = 0;
+ float[] pt1 = new float[2];
+ float[] pt2 = new float[2];
+ for (int iy = 0 ; iy < h ; iy++) {
for (int ix = 0 ; ix < w ; ix++) {
- line[ix] = getColor(ix + x, mX0, mDx);
- }
+ // handle the canvas transform
+ pt1[0] = x + ix;
+ pt1[1] = y + iy;
+ mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
- for (int iy = 0 ; iy < h ; iy++) {
- System.arraycopy(line, 0, data, iy*w, line.length);
- }
- } else {
- int index = 0;
- for (int iy = 0 ; iy < h ; iy++) {
- for (int ix = 0 ; ix < w ; ix++) {
- data[index++] = getColor(ix + x, iy + y);
- }
+ // handle the local matrix.
+ pt1[0] = pt2[0];
+ pt1[1] = pt2[1];
+ mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+ data[index++] = getColor(pt2[0], pt2[1]);
}
}
@@ -199,13 +214,6 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
}
}
- /** Returns a color for the easy vertical/horizontal mode */
- private int getColor(float absPos, float refPos, float refSize) {
- float pos = (absPos - refPos) / refSize;
-
- return getGradientColor(pos);
- }
-
/**
* Returns a color for an arbitrary point.
*/
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index bef8c8c..6b43544 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -471,7 +471,7 @@ public final class Matrix_Delegate {
return false;
}
- d.preTransform(getRotate(degrees, px, py));
+ d.postTransform(getRotate(degrees, px, py));
return true;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index c36ce53..eebf378 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -16,11 +16,14 @@
package android.graphics;
+import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import android.graphics.Shader.TileMode;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
/**
* Delegate implementing the native methods of android.graphics.RadialGradient
@@ -105,18 +108,17 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
private RadialGradient_Delegate(float x, float y, float radius, int colors[], float positions[],
TileMode tile) {
super(colors, positions);
-
mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
}
- private static class RadialGradientPaint extends GradientPaint {
+ private class RadialGradientPaint extends GradientPaint {
private final float mX;
private final float mY;
private final float mRadius;
- public RadialGradientPaint(float x, float y, float radius, int[] colors, float[] positions,
- TileMode mode) {
+ public RadialGradientPaint(float x, float y, float radius,
+ int[] colors, float[] positions, TileMode mode) {
super(colors, positions, mode);
mX = x;
mY = y;
@@ -130,14 +132,36 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
java.awt.geom.AffineTransform xform,
java.awt.RenderingHints hints) {
precomputeGradientColors();
- return new RadialGradientPaintContext(colorModel);
+
+ AffineTransform canvasMatrix;
+ try {
+ canvasMatrix = xform.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
+ canvasMatrix = new AffineTransform();
+ }
+
+ AffineTransform localMatrix = getLocalMatrix();
+ try {
+ localMatrix = localMatrix.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
+ localMatrix = new AffineTransform();
+ }
+
+ return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
}
private class RadialGradientPaintContext implements java.awt.PaintContext {
+ private final AffineTransform mCanvasMatrix;
+ private final AffineTransform mLocalMatrix;
private final java.awt.image.ColorModel mColorModel;
- public RadialGradientPaintContext(java.awt.image.ColorModel colorModel) {
+ public RadialGradientPaintContext(AffineTransform canvasMatrix,
+ AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+ mCanvasMatrix = canvasMatrix;
+ mLocalMatrix = localMatrix;
mColorModel = colorModel;
}
@@ -157,10 +181,22 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
// compute distance from each point to the center, and figure out the distance from
// it.
int index = 0;
+ float[] pt1 = new float[2];
+ float[] pt2 = new float[2];
for (int iy = 0 ; iy < h ; iy++) {
for (int ix = 0 ; ix < w ; ix++) {
- float _x = x + ix - mX;
- float _y = y + iy - mY;
+ // handle the canvas transform
+ pt1[0] = x + ix;
+ pt1[1] = y + iy;
+ mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+ // handle the local matrix
+ pt1[0] = pt2[0] - mX;
+ pt1[1] = pt2[1] - mY;
+ mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+ float _x = pt2[0];
+ float _y = pt2[1];
float distance = (float) Math.sqrt(_x * _x + _y * _y);
data[index++] = getGradientColor(distance / mRadius);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 646ac80..7bf1443 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -18,6 +18,8 @@ package android.graphics;
import com.android.layoutlib.bridge.impl.DelegateManager;
+import java.awt.geom.AffineTransform;
+
/**
* Delegate implementing the native methods of android.graphics.Shader
*
@@ -109,4 +111,19 @@ public abstract class Shader_Delegate {
// ---- Private delegate/helper methods ----
+ protected AffineTransform getLocalMatrix() {
+ Matrix_Delegate localMatrixDelegate = null;
+ if (mLocalMatrix > 0) {
+ localMatrixDelegate = Matrix_Delegate.getDelegate(mLocalMatrix);
+ if (localMatrixDelegate == null) {
+ assert false;
+ return new AffineTransform();
+ }
+
+ return localMatrixDelegate.getAffineTransform();
+ }
+
+ return new AffineTransform();
+ }
+
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 358c3c7..97c3cfd 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -16,9 +16,12 @@
package android.graphics;
+import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
/**
* Delegate implementing the native methods of android.graphics.SweepGradient
@@ -90,16 +93,16 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
private SweepGradient_Delegate(float cx, float cy,
int colors[], float positions[]) {
super(colors, positions);
-
mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
}
- private static class SweepGradientPaint extends GradientPaint {
+ private class SweepGradientPaint extends GradientPaint {
private final float mCx;
private final float mCy;
- public SweepGradientPaint(float cx, float cy, int[] colors, float[] positions) {
+ public SweepGradientPaint(float cx, float cy, int[] colors,
+ float[] positions) {
super(colors, positions, null /*tileMode*/);
mCx = cx;
mCy = cy;
@@ -112,14 +115,36 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
java.awt.geom.AffineTransform xform,
java.awt.RenderingHints hints) {
precomputeGradientColors();
- return new SweepGradientPaintContext(colorModel);
+
+ AffineTransform canvasMatrix;
+ try {
+ canvasMatrix = xform.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
+ canvasMatrix = new AffineTransform();
+ }
+
+ AffineTransform localMatrix = getLocalMatrix();
+ try {
+ localMatrix = localMatrix.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
+ localMatrix = new AffineTransform();
+ }
+
+ return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
}
private class SweepGradientPaintContext implements java.awt.PaintContext {
+ private final AffineTransform mCanvasMatrix;
+ private final AffineTransform mLocalMatrix;
private final java.awt.image.ColorModel mColorModel;
- public SweepGradientPaintContext(java.awt.image.ColorModel colorModel) {
+ public SweepGradientPaintContext(AffineTransform canvasMatrix,
+ AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
+ mCanvasMatrix = canvasMatrix;
+ mLocalMatrix = localMatrix;
mColorModel = colorModel;
}
@@ -139,10 +164,23 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
// compute angle from each point to the center, and figure out the distance from
// it.
int index = 0;
+ float[] pt1 = new float[2];
+ float[] pt2 = new float[2];
for (int iy = 0 ; iy < h ; iy++) {
for (int ix = 0 ; ix < w ; ix++) {
- float dx = x + ix - mCx;
- float dy = y + iy - mCy;
+ // handle the canvas transform
+ pt1[0] = x + ix;
+ pt1[1] = y + iy;
+ mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+ // handle the local matrix
+ pt1[0] = pt2[0] - mCx;
+ pt1[1] = pt2[1] - mCy;
+ mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+ float dx = pt2[0];
+ float dy = pt2[1];
+
float angle;
if (dx == 0) {
angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);