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

Commit ace6a5cf authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 21408 into donut

* changes:
  Improved drawing/matrix support in layoutlib
parents f5e6a211 2473ef56
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.graphics;

import com.android.layoutlib.bridge.BridgeCanvas;

import java.awt.image.BufferedImage;
import java.io.File;
@@ -66,7 +65,6 @@ public final class Bitmap extends _Original_Bitmap {
        };
    }

    
    @Override
    public int getWidth() {
        return mImage.getWidth();
@@ -158,7 +156,7 @@ public final class Bitmap extends _Original_Bitmap {
        neww = Math.round(deviceR.width());
        newh = Math.round(deviceR.height());

        BridgeCanvas canvas = new BridgeCanvas(neww, newh);
        Canvas canvas = new Canvas(neww, newh);

        canvas.translate(-deviceR.left, -deviceR.top);
        canvas.concat(m);
+188 −111
Original line number Diff line number Diff line
@@ -14,24 +14,16 @@
 * limitations under the License.
 */

package com.android.layoutlib.bridge;
package android.graphics;

import com.android.layoutlib.api.ILayoutLog;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.DrawFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.Xfermode;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
@@ -43,6 +35,7 @@ import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.Stack;

@@ -51,31 +44,54 @@ import javax.microedition.khronos.opengles.GL;
/**
 * Re-implementation of the Canvas, 100% in java on top of a BufferedImage.
 */
public class BridgeCanvas extends Canvas {
public class Canvas extends _Original_Canvas {

    private BufferedImage mBufferedImage;
    private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>();
    private final ILayoutLog mLogger;

    public BridgeCanvas(int width, int height, ILayoutLog logger) {
    public Canvas() {
        mLogger = null;
        // the mBufferedImage will be taken from a bitmap in #setBitmap()
    }

    public Canvas(Bitmap bitmap) {
        mLogger = null;
        mBufferedImage = bitmap.getImage();
        mGraphicsStack.push(mBufferedImage.createGraphics());
    }

    public Canvas(int nativeCanvas) {
        mLogger = null;
        throw new UnsupportedOperationException("Can't create Canvas(int)");
    }

    public Canvas(javax.microedition.khronos.opengles.GL gl) {
        mLogger = null;
        throw new UnsupportedOperationException("Can't create Canvas(javax.microedition.khronos.opengles.GL)");
    }

    // custom constructors for our use.
    public Canvas(int width, int height, ILayoutLog logger) {
        mLogger = logger;
        mBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        mGraphicsStack.push(mBufferedImage.createGraphics());
    }

    public BridgeCanvas(int width, int height) {
    public Canvas(int width, int height) {
        this(width, height, null /* logger*/);
    }

    // custom mehtods
    public BufferedImage getImage() {
        return mBufferedImage;
    }

    Graphics2D getGraphics2d() {
    public Graphics2D getGraphics2d() {
        return mGraphicsStack.peek();
    }

    void dispose() {
    public void dispose() {
        while (mGraphicsStack.size() > 0) {
            mGraphicsStack.pop().dispose();
        }
@@ -169,6 +185,25 @@ public class BridgeCanvas extends Canvas {
        }
    }


    // --------------------
    // OVERRIDEN ENUMS
    // This is needed since we rename Canvas into _Original_Canvas
    // --------------------

    public enum EdgeType {
        BW(0),  //!< treat edges by just rounding to nearest pixel boundary
        AA(1);  //!< treat edges by rounding-out, since they may be antialiased

        EdgeType(int nativeInt) {
            this.nativeInt = nativeInt;
        }
        final int nativeInt;
    }


    // --------------------
    // OVERRIDEN METHODS
    // --------------------

    @Override
@@ -176,6 +211,16 @@ public class BridgeCanvas extends Canvas {
        // pass
    }

    /* (non-Javadoc)
     * @see android.graphics.Canvas#setBitmap(android.graphics.Bitmap)
     */
    @Override
    public void setBitmap(Bitmap bitmap) {
        mBufferedImage = bitmap.getImage();
        mGraphicsStack.push(mBufferedImage.createGraphics());
    }


    /* (non-Javadoc)
     * @see android.graphics.Canvas#translate(float, float)
     */
@@ -289,22 +334,35 @@ public class BridgeCanvas extends Canvas {
        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
    }

    @Override
    public boolean quickReject(RectF rect, EdgeType type) {
        return false;
    }

    @Override
    public boolean quickReject(RectF rect, _Original_Canvas.EdgeType type) {
        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
    }

    public boolean quickReject(Path path, EdgeType type) {
        return false;
    }

    @Override
    public boolean quickReject(Path path, _Original_Canvas.EdgeType type) {
        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
    }

    public boolean quickReject(float left, float top, float right, float bottom,
                               EdgeType type) {
        return false;
    }

    @Override
    public boolean quickReject(float left, float top, float right, float bottom,
                               _Original_Canvas.EdgeType type) {
        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
    }

    /**
     * Retrieve the clip bounds, returning true if they are non-empty.
     *
@@ -417,7 +475,32 @@ public class BridgeCanvas extends Canvas {
     */
    @Override
    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
        throw new UnsupportedOperationException();
        boolean needsRestore = false;
        if (matrix.isIdentity() == false) {
            // create a new graphics and apply the matrix to it
            save(); // this creates a new Graphics2D, and stores it for children call to use
            needsRestore = true;
            Graphics2D g = getGraphics2d(); // get the newly create Graphics2D

            // get the Graphics2D current matrix
            AffineTransform currentTx = g.getTransform();
            // get the AffineTransform from the matrix
            AffineTransform matrixTx = matrix.getTransform();

            // combine them so that the matrix is applied after.
            currentTx.preConcatenate(matrixTx);

            // give it to the graphics as a new matrix replacing all previous transform
            g.setTransform(currentTx);
        }

        // draw the bitmap
        drawBitmap(bitmap, 0, 0, paint);

        if (needsRestore) {
            // remove the new graphics
            restore();
        }
    }

    /* (non-Javadoc)
@@ -465,6 +548,7 @@ public class BridgeCanvas extends Canvas {

        Composite c = null;

        if (paint != null) {
            if (paint.isFilterBitmap()) {
                g = (Graphics2D)g.create();
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
@@ -476,18 +560,20 @@ public class BridgeCanvas extends Canvas {
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                        paint.getAlpha()/255.f));
            }
        }

        g.drawImage(image, dleft, dtop, dright, dbottom,
                sleft, stop, sright, sbottom, null);

        if (paint != null) {
            if (paint.isFilterBitmap()) {
                g.dispose();
            }
        
            if (c != null) {
                g.setComposite(c);
            }
        }
    }

    /* (non-Javadoc)
     * @see android.graphics.Canvas#rotate(float, float, float)
@@ -1058,15 +1144,6 @@ public class BridgeCanvas extends Canvas {
        return super.saveLayerAlpha(bounds, alpha, saveFlags);
    }

    /* (non-Javadoc)
     * @see android.graphics.Canvas#setBitmap(android.graphics.Bitmap)
     */
    @Override
    public void setBitmap(Bitmap bitmap) {
        // TODO Auto-generated method stub
        super.setBitmap(bitmap);
    }

    /* (non-Javadoc)
     * @see android.graphics.Canvas#setDrawFilter(android.graphics.DrawFilter)
     */
+52 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.graphics;

import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;


/**
@@ -747,7 +748,24 @@ public class Matrix extends _Original_Matrix {
     * inverted, ignore inverse and return false.
     */
    public boolean invert(Matrix inverse) {
        throw new UnsupportedOperationException("STUB NEEDED");
        if (inverse == null) {
            return false;
        }

        try {
            AffineTransform affineTransform = getTransform();
            AffineTransform inverseTransform = affineTransform.createInverse();
            inverse.mValues[0] = (float)inverseTransform.getScaleX();
            inverse.mValues[1] = (float)inverseTransform.getShearX();
            inverse.mValues[2] = (float)inverseTransform.getTranslateX();
            inverse.mValues[3] = (float)inverseTransform.getScaleX();
            inverse.mValues[4] = (float)inverseTransform.getShearY();
            inverse.mValues[5] = (float)inverseTransform.getTranslateY();

            return true;
        } catch (NoninvertibleTransformException e) {
            return false;
        }
    }

    @Override
@@ -770,7 +788,19 @@ public class Matrix extends _Original_Matrix {
    public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
                          int pointCount) {
        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
        throw new UnsupportedOperationException("STUB NEEDED");

        for (int i = 0 ; i < pointCount ; i++) {
            // just in case we are doing in place, we better put this in temp vars
            float x = mValues[0] * src[i + srcIndex] +
                      mValues[1] * src[i + srcIndex + 1] +
                      mValues[2];
            float y = mValues[3] * src[i + srcIndex] +
                      mValues[4] * src[i + srcIndex + 1] +
                      mValues[5];

            dst[i + dstIndex]     = x;
            dst[i + dstIndex + 1] = y;
        }
    }

    /**
@@ -858,7 +888,26 @@ public class Matrix extends _Original_Matrix {
        if (dst == null || src == null) {
            throw new NullPointerException();
        }
        throw new UnsupportedOperationException("STUB NEEDED");

        // array with 4 corners
        float[] corners = new float[] {
                src.left, src.top,
                src.right, src.top,
                src.right, src.bottom,
                src.left, src.bottom,
        };

        // apply the transform to them.
        mapPoints(corners);

        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));

        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));

        return rectStaysRect();
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Typeface;
@@ -401,8 +402,7 @@ public final class Bridge implements ILayoutBridge {
            view.layout(0, screenOffset, screenWidth, screenHeight);

            // draw them
            BridgeCanvas canvas = new BridgeCanvas(screenWidth, screenHeight - screenOffset,
                    logger);
            Canvas canvas = new Canvas(screenWidth, screenHeight - screenOffset, logger);

            root.draw(canvas);
            canvas.dispose();
+11 −17
Original line number Diff line number Diff line
@@ -79,18 +79,12 @@ public class NinePatchDrawable extends Drawable {

    @Override
    public void draw(Canvas canvas) {
        if (canvas instanceof BridgeCanvas) {
            BridgeCanvas bridgeCanvas = (BridgeCanvas)canvas;
            
        Rect r = getBounds();
            m9Patch.draw(bridgeCanvas.getGraphics2d(), r.left, r.top, r.width(), r.height());
        m9Patch.draw(canvas.getGraphics2d(), r.left, r.top, r.width(), r.height());

        return;
    }

        throw new UnsupportedOperationException();
    }


    // ----------- Not implemented methods ---------------

Loading