Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21534cfc authored by Xavier Ducrohet's avatar Xavier Ducrohet Committed by Android (Google) Code Review
Browse files

Merge "LayoutLib: Fix gradient rendering."

parents 644b75ed d9c64369
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -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;
+47 −39
Original line number Diff line number Diff line
@@ -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;
@@ -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;
                float[] pt1 = new float[2];
                float[] pt2 = new float[2];
                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];
                    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.
         */
+1 −1
Original line number Diff line number Diff line
@@ -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;
    }

+44 −8
Original line number Diff line number Diff line
@@ -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);
+17 −0
Original line number Diff line number Diff line
@@ -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();
    }

}
Loading