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

Commit 37828821 authored by Andrew Shulaev's avatar Andrew Shulaev Committed by Android (Google) Code Review
Browse files

Merge "Added function to render a drawable in all available states"

parents d5e11f6f 1f158819
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
     */
    private static LayoutLog sCurrentLog = sDefaultLog;

    private static final int LAST_SUPPORTED_FEATURE = Features.PREFERENCES_RENDERING;
    private static final int LAST_SUPPORTED_FEATURE = Features.RENDER_ALL_DRAWABLE_STATES;

    @Override
    public int getApiLevel() {
+10 −8
Original line number Diff line number Diff line
@@ -16,22 +16,24 @@

package com.android.layoutlib.bridge.android;

import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.Key;

/**
 * This contains all known keys for the {@link SessionParams#getFlag(SessionParams.Key)}.
 * This contains all known keys for the {@link RenderParams#getFlag(Key)}.
 * <p/>
 * The IDE has its own copy of this class which may be newer or older than this one.
 * <p/>
 * Constants should never be modified or removed from this class.
 */
public final class SessionParamsFlags {
public final class RenderParamsFlags {

    public static final SessionParams.Key<String> FLAG_KEY_ROOT_TAG =
            new SessionParams.Key<String>("rootTag", String.class);
    public static final SessionParams.Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
            new SessionParams.Key<Boolean>("disableBitmapCaching", Boolean.class);
    public static final Key<String> FLAG_KEY_ROOT_TAG =
            new Key<String>("rootTag", String.class);
    public static final Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
            new Key<Boolean>("disableBitmapCaching", Boolean.class);
    public static final Key<Boolean> FLAG_KEY_RENDER_ALL_DRAWABLE_STATES =
            new Key<Boolean>("renderAllDrawableStates", Boolean.class);

    // Disallow instances.
    private SessionParamsFlags() {}
    private RenderParamsFlags() {}
}
+54 −8
Original line number Diff line number Diff line
@@ -16,20 +16,20 @@

package com.android.layoutlib.bridge.impl;

import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;

import com.android.ide.common.rendering.api.DrawableParams;
import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result.Status;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.resources.ResourceType;

import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.view.AttachInfo_Accessor;
import android.view.View.MeasureSpec;
import android.widget.FrameLayout;
@@ -38,7 +38,9 @@ import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
@@ -71,11 +73,37 @@ public class RenderDrawable extends RenderAction<DrawableParams> {
            return Status.ERROR_NOT_A_DRAWABLE.createResult();
        }

        Drawable d = ResourceHelper.getDrawable(drawableResource, context);

        final Boolean allStates =
                params.getFlag(RenderParamsFlags.FLAG_KEY_RENDER_ALL_DRAWABLE_STATES);
        if (allStates == Boolean.TRUE) {
            final List<BufferedImage> result;

            if (d instanceof StateListDrawable) {
                result = new ArrayList<BufferedImage>();
                final StateListDrawable stateList = (StateListDrawable) d;
                for (int i = 0; i < stateList.getStateCount(); i++) {
                    final Drawable stateDrawable = stateList.getStateDrawable(i);
                    result.add(renderImage(hardwareConfig, stateDrawable, context));
                }
            } else {
                result = Collections.singletonList(renderImage(hardwareConfig, d, context));
            }

            return Status.SUCCESS.createResult(result);
        } else {
            BufferedImage image = renderImage(hardwareConfig, d, context);
            return Status.SUCCESS.createResult(image);
        }
    }

    private BufferedImage renderImage(HardwareConfig hardwareConfig, Drawable d,
            BridgeContext context) {
        // create a simple FrameLayout
        FrameLayout content = new FrameLayout(context);

        // get the actual Drawable object to draw
        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
        content.setBackground(d);

        // set the AttachInfo on the root view.
@@ -83,8 +111,27 @@ public class RenderDrawable extends RenderAction<DrawableParams> {


        // measure
        int w = hardwareConfig.getScreenWidth();
        int h = hardwareConfig.getScreenHeight();
        int w = d.getIntrinsicWidth();
        int h = d.getIntrinsicHeight();

        final int screenWidth = hardwareConfig.getScreenWidth();
        final int screenHeight = hardwareConfig.getScreenHeight();

        if (w == -1 || h == -1) {
            // Use screen size when either intrinsic width or height isn't available
            w = screenWidth;
            h = screenHeight;
        } else if (w > screenWidth || h > screenHeight) {
            // If image wouldn't fit to the screen, resize it to avoid cropping.

            // We need to find scale such that scale * w <= screenWidth, scale * h <= screenHeight
            double scale = Math.min((double) screenWidth / w, (double) screenHeight / h);

            // scale * w / scale * h = w / h, so, proportions are preserved.
            w = (int) Math.floor(scale * w);
            h = (int) Math.floor(scale * h);
        }

        int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
        int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        content.measure(w_spec, h_spec);
@@ -108,8 +155,7 @@ public class RenderDrawable extends RenderAction<DrawableParams> {

        // and draw
        content.draw(canvas);

        return Status.SUCCESS.createResult(image);
        return image;
    }

    protected BufferedImage getImage(int w, int h) {
+3 −3
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.SessionParamsFlags;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.bars.BridgeActionBar;
import com.android.layoutlib.bridge.bars.AppCompatActionBar;
import com.android.layoutlib.bridge.bars.Config;
@@ -400,7 +400,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
            // it can instantiate the custom Fragment.
            Fragment_Delegate.setProjectCallback(params.getProjectCallback());

            String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG);
            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
            boolean isPreference = "PreferenceScreen".equals(rootTag);
            View view;
            if (isPreference) {
@@ -557,7 +557,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
                // This is useful when mImage is just a wrapper of Graphics2D so
                // it doesn't get cached.
                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
                    SessionParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
                if (newRenderSize || mCanvas == null || disableBitmapCaching) {
                    if (params.getImageFactory() != null) {
                        mImage = params.getImageFactory().getImage(