Search in sources :

Example 16 with HardwareConfig

use of com.android.ide.common.rendering.api.HardwareConfig in project platform_frameworks_base by android.

the class RenderDrawable method render.

public Result render() {
    checkLock();
    // get the drawable resource value
    DrawableParams params = getParams();
    HardwareConfig hardwareConfig = params.getHardwareConfig();
    ResourceValue drawableResource = params.getDrawable();
    // resolve it
    BridgeContext context = getContext();
    drawableResource = context.getRenderResources().resolveResValue(drawableResource);
    if (drawableResource == null) {
        return Status.ERROR_NOT_A_DRAWABLE.createResult();
    }
    ResourceType resourceType = drawableResource.getResourceType();
    if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
        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);
    }
}
Also used : HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) Drawable(android.graphics.drawable.Drawable) StateListDrawable(android.graphics.drawable.StateListDrawable) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) ResourceType(com.android.resources.ResourceType) StateListDrawable(android.graphics.drawable.StateListDrawable) BufferedImage(java.awt.image.BufferedImage) DrawableParams(com.android.ide.common.rendering.api.DrawableParams)

Example 17 with HardwareConfig

use of com.android.ide.common.rendering.api.HardwareConfig in project platform_frameworks_base by android.

the class RenderSessionImpl method measure.

/**
     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
     */
private void measure(@NonNull SessionParams params) {
    // only do the screen measure when needed.
    if (mMeasuredScreenWidth != -1) {
        return;
    }
    RenderingMode renderingMode = params.getRenderingMode();
    HardwareConfig hardwareConfig = params.getHardwareConfig();
    mNewRenderSize = true;
    mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
    mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
    if (renderingMode != RenderingMode.NORMAL) {
        int widthMeasureSpecMode = renderingMode.isHorizExpand() ? // this lets us know the actual needed size
        MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
        int heightMeasureSpecMode = renderingMode.isVertExpand() ? // this lets us know the actual needed size
        MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
        // We used to compare the measured size of the content to the screen size but
        // this does not work anymore due to the 2 following issues:
        // - If the content is in a decor (system bar, title/action bar), the root view
        //   will not resize even with the UNSPECIFIED because of the embedded layout.
        // - If there is no decor, but a dialog frame, then the dialog padding prevents
        //   comparing the size of the content to the screen frame (as it would not
        //   take into account the dialog padding).
        // The solution is to first get the content size in a normal rendering, inside
        // the decor or the dialog padding.
        // Then measure only the content with UNSPECIFIED to see the size difference
        // and apply this to the screen size.
        // first measure the full layout, with EXACTLY to get the size of the
        // content as it is inside the decor/dialog
        @SuppressWarnings("deprecation") Pair<Integer, Integer> exactMeasure = measureView(mViewRoot, mContentRoot.getChildAt(0), mMeasuredScreenWidth, MeasureSpec.EXACTLY, mMeasuredScreenHeight, MeasureSpec.EXACTLY);
        // now measure the content only using UNSPECIFIED (where applicable, based on
        // the rendering mode). This will give us the size the content needs.
        @SuppressWarnings("deprecation") Pair<Integer, Integer> result = measureView(mContentRoot, mContentRoot.getChildAt(0), mMeasuredScreenWidth, widthMeasureSpecMode, mMeasuredScreenHeight, heightMeasureSpecMode);
        // now look at the difference and add what is needed.
        if (renderingMode.isHorizExpand()) {
            int measuredWidth = exactMeasure.getFirst();
            int neededWidth = result.getFirst();
            if (neededWidth > measuredWidth) {
                mMeasuredScreenWidth += neededWidth - measuredWidth;
            }
            if (mMeasuredScreenWidth < measuredWidth) {
                // If the screen width is less than the exact measured width,
                // expand to match.
                mMeasuredScreenWidth = measuredWidth;
            }
        }
        if (renderingMode.isVertExpand()) {
            int measuredHeight = exactMeasure.getSecond();
            int neededHeight = result.getSecond();
            if (neededHeight > measuredHeight) {
                mMeasuredScreenHeight += neededHeight - measuredHeight;
            }
            if (mMeasuredScreenHeight < measuredHeight) {
                // If the screen height is less than the exact measured height,
                // expand to match.
                mMeasuredScreenHeight = measuredHeight;
            }
        }
    }
}
Also used : RenderingMode(com.android.ide.common.rendering.api.SessionParams.RenderingMode) HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig)

Example 18 with HardwareConfig

use of com.android.ide.common.rendering.api.HardwareConfig in project android_frameworks_base by ParanoidAndroid.

the class RenderAction method init.

/**
     * Initializes and acquires the scene, creating various Android objects such as context,
     * inflater, and parser.
     *
     * @param timeout the time to wait if another rendering is happening.
     *
     * @return whether the scene was prepared
     *
     * @see #acquire(long)
     * @see #release()
     */
public Result init(long timeout) {
    // acquire the lock. if the result is null, lock was just acquired, otherwise, return
    // the result.
    Result result = acquireLock(timeout);
    if (result != null) {
        return result;
    }
    HardwareConfig hardwareConfig = mParams.getHardwareConfig();
    // setup the display Metrics.
    DisplayMetrics metrics = new DisplayMetrics();
    metrics.densityDpi = metrics.noncompatDensityDpi = hardwareConfig.getDensity().getDpiValue();
    metrics.density = metrics.noncompatDensity = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
    metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
    metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
    metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
    metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
    metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
    RenderResources resources = mParams.getResources();
    // build the context
    mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources, mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion());
    setUp();
    return SUCCESS.createResult();
}
Also used : HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig) RenderResources(com.android.ide.common.rendering.api.RenderResources) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) DisplayMetrics(android.util.DisplayMetrics) Result(com.android.ide.common.rendering.api.Result)

Example 19 with HardwareConfig

use of com.android.ide.common.rendering.api.HardwareConfig in project android_frameworks_base by ParanoidAndroid.

the class RenderDrawable method render.

public Result render() {
    checkLock();
    try {
        // get the drawable resource value
        DrawableParams params = getParams();
        HardwareConfig hardwareConfig = params.getHardwareConfig();
        ResourceValue drawableResource = params.getDrawable();
        // resolve it
        BridgeContext context = getContext();
        drawableResource = context.getRenderResources().resolveResValue(drawableResource);
        if (drawableResource == null || drawableResource.getResourceType() != ResourceType.DRAWABLE) {
            return Status.ERROR_NOT_A_DRAWABLE.createResult();
        }
        // 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.
        AttachInfo_Accessor.setAttachInfo(content);
        // measure
        int w = hardwareConfig.getScreenWidth();
        int h = hardwareConfig.getScreenHeight();
        int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
        int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
        content.measure(w_spec, h_spec);
        // now do the layout.
        content.layout(0, 0, w, h);
        // preDraw setup
        AttachInfo_Accessor.dispatchOnPreDraw(content);
        // draw into a new image
        BufferedImage image = getImage(w, h);
        // create an Android bitmap around the BufferedImage
        Bitmap bitmap = Bitmap_Delegate.createBitmap(image, true, /*isMutable*/
        hardwareConfig.getDensity());
        // create a Canvas around the Android bitmap
        Canvas canvas = new Canvas(bitmap);
        canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
        // and draw
        content.draw(canvas);
        return Status.SUCCESS.createResult(image);
    } catch (IOException e) {
        return ERROR_UNKNOWN.createResult(e.getMessage(), e);
    }
}
Also used : Bitmap(android.graphics.Bitmap) HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig) FrameLayout(android.widget.FrameLayout) Canvas(android.graphics.Canvas) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) Drawable(android.graphics.drawable.Drawable) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) IOException(java.io.IOException) BufferedImage(java.awt.image.BufferedImage) DrawableParams(com.android.ide.common.rendering.api.DrawableParams)

Example 20 with HardwareConfig

use of com.android.ide.common.rendering.api.HardwareConfig in project android_frameworks_base by ParanoidAndroid.

the class RenderSessionImpl method render.

/**
     * Renders the scene.
     * <p>
     * {@link #acquire(long)} must have been called before this.
     *
     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
     *      the case where bitmaps are reused). This is typically needed when not playing
     *      animations.)
     *
     * @throws IllegalStateException if the current context is different than the one owned by
     *      the scene, or if {@link #acquire(long)} was not called.
     *
     * @see RenderParams#getRenderingMode()
     * @see RenderSession#render(long)
     */
public Result render(boolean freshRender) {
    checkLock();
    SessionParams params = getParams();
    try {
        if (mViewRoot == null) {
            return ERROR_NOT_INFLATED.createResult();
        }
        RenderingMode renderingMode = params.getRenderingMode();
        HardwareConfig hardwareConfig = params.getHardwareConfig();
        // only do the screen measure when needed.
        boolean newRenderSize = false;
        if (mMeasuredScreenWidth == -1) {
            newRenderSize = true;
            mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
            mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
            if (renderingMode != RenderingMode.NORMAL) {
                int widthMeasureSpecMode = renderingMode.isHorizExpand() ? // this lets us know the actual needed size
                MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
                int heightMeasureSpecMode = renderingMode.isVertExpand() ? // this lets us know the actual needed size
                MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
                // We used to compare the measured size of the content to the screen size but
                // this does not work anymore due to the 2 following issues:
                // - If the content is in a decor (system bar, title/action bar), the root view
                //   will not resize even with the UNSPECIFIED because of the embedded layout.
                // - If there is no decor, but a dialog frame, then the dialog padding prevents
                //   comparing the size of the content to the screen frame (as it would not
                //   take into account the dialog padding).
                // The solution is to first get the content size in a normal rendering, inside
                // the decor or the dialog padding.
                // Then measure only the content with UNSPECIFIED to see the size difference
                // and apply this to the screen size.
                // first measure the full layout, with EXACTLY to get the size of the
                // content as it is inside the decor/dialog
                Pair<Integer, Integer> exactMeasure = measureView(mViewRoot, mContentRoot.getChildAt(0), mMeasuredScreenWidth, MeasureSpec.EXACTLY, mMeasuredScreenHeight, MeasureSpec.EXACTLY);
                // now measure the content only using UNSPECIFIED (where applicable, based on
                // the rendering mode). This will give us the size the content needs.
                Pair<Integer, Integer> result = measureView(mContentRoot, mContentRoot.getChildAt(0), mMeasuredScreenWidth, widthMeasureSpecMode, mMeasuredScreenHeight, heightMeasureSpecMode);
                // now look at the difference and add what is needed.
                if (renderingMode.isHorizExpand()) {
                    int measuredWidth = exactMeasure.getFirst();
                    int neededWidth = result.getFirst();
                    if (neededWidth > measuredWidth) {
                        mMeasuredScreenWidth += neededWidth - measuredWidth;
                    }
                }
                if (renderingMode.isVertExpand()) {
                    int measuredHeight = exactMeasure.getSecond();
                    int neededHeight = result.getSecond();
                    if (neededHeight > measuredHeight) {
                        mMeasuredScreenHeight += neededHeight - measuredHeight;
                    }
                }
            }
        }
        // measure again with the size we need
        // This must always be done before the call to layout
        measureView(mViewRoot, null, /*measuredView*/
        mMeasuredScreenWidth, MeasureSpec.EXACTLY, mMeasuredScreenHeight, MeasureSpec.EXACTLY);
        // now do the layout.
        mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
        if (params.isLayoutOnly()) {
            // delete the canvas and image to reset them on the next full rendering
            mImage = null;
            mCanvas = null;
        } else {
            AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot);
            // draw the views
            // create the BufferedImage into which the layout will be rendered.
            boolean newImage = false;
            if (newRenderSize || mCanvas == null) {
                if (params.getImageFactory() != null) {
                    mImage = params.getImageFactory().getImage(mMeasuredScreenWidth, mMeasuredScreenHeight);
                } else {
                    mImage = new BufferedImage(mMeasuredScreenWidth, mMeasuredScreenHeight, BufferedImage.TYPE_INT_ARGB);
                    newImage = true;
                }
                if (params.isBgColorOverridden()) {
                    // since we override the content, it's the same as if it was a new image.
                    newImage = true;
                    Graphics2D gc = mImage.createGraphics();
                    gc.setColor(new Color(params.getOverrideBgColor(), true));
                    gc.setComposite(AlphaComposite.Src);
                    gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
                    gc.dispose();
                }
                // create an Android bitmap around the BufferedImage
                Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage, true, /*isMutable*/
                hardwareConfig.getDensity());
                // create a Canvas around the Android bitmap
                mCanvas = new Canvas(bitmap);
                mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
            }
            if (freshRender && newImage == false) {
                Graphics2D gc = mImage.createGraphics();
                gc.setComposite(AlphaComposite.Src);
                gc.setColor(new Color(0x00000000, true));
                gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
                // done
                gc.dispose();
            }
            mViewRoot.draw(mCanvas);
        }
        mViewInfoList = startVisitingViews(mViewRoot, 0, params.getExtendedViewInfoMode());
        // success!
        return SUCCESS.createResult();
    } catch (Throwable e) {
        // get the real cause of the exception.
        Throwable t = e;
        while (t.getCause() != null) {
            t = t.getCause();
        }
        return ERROR_UNKNOWN.createResult(t.getMessage(), t);
    }
}
Also used : SessionParams(com.android.ide.common.rendering.api.SessionParams) HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig) Color(java.awt.Color) Canvas(android.graphics.Canvas) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) Bitmap(android.graphics.Bitmap) RenderingMode(com.android.ide.common.rendering.api.SessionParams.RenderingMode)

Aggregations

HardwareConfig (com.android.ide.common.rendering.api.HardwareConfig)33 BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)13 BufferedImage (java.awt.image.BufferedImage)12 Result (com.android.ide.common.rendering.api.Result)11 Bitmap (android.graphics.Bitmap)7 Canvas (android.graphics.Canvas)7 Drawable (android.graphics.drawable.Drawable)7 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)7 SessionParams (com.android.ide.common.rendering.api.SessionParams)7 Configuration (android.content.res.Configuration)6 DisplayMetrics (android.util.DisplayMetrics)6 DrawableParams (com.android.ide.common.rendering.api.DrawableParams)6 RenderResources (com.android.ide.common.rendering.api.RenderResources)6 RenderingMode (com.android.ide.common.rendering.api.SessionParams.RenderingMode)6 Density (com.android.resources.Density)6 ScreenOrientation (com.android.resources.ScreenOrientation)6 ScreenSize (com.android.resources.ScreenSize)6 Color (java.awt.Color)6 Graphics2D (java.awt.Graphics2D)6 StateListDrawable (android.graphics.drawable.StateListDrawable)5