Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +29 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,14 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; import com.android.ide.common.rendering.api.Capability; import com.android.ide.common.rendering.api.DrawableParams; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.SessionParams; import com.android.layoutlib.bridge.android.BridgeAssetManager; import com.android.layoutlib.bridge.impl.FontLoader; import com.android.layoutlib.bridge.impl.RenderDrawable; import com.android.layoutlib.bridge.impl.RenderSessionImpl; import com.android.ninepatch.NinePatchChunk; import com.android.resources.ResourceType; Loading Loading @@ -331,6 +333,33 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { } } @Override public Result renderDrawable(DrawableParams params) { try { Result lastResult = SUCCESS.createResult(); RenderDrawable action = new RenderDrawable(params); try { prepareThread(); lastResult = action.init(params.getTimeout()); if (lastResult.isSuccess()) { lastResult = action.render(); } } finally { action.release(); cleanupThread(); } return lastResult; } catch (Throwable t) { // get the real cause of the exception. Throwable t2 = t; while (t2.getCause() != null) { t2 = t.getCause(); } return ERROR_UNKNOWN.createResult(t2.getMessage(), t); } } @Override public void clearCaches(Object projectKey) { if (projectKey != null) { Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +8 −6 Original line number Diff line number Diff line Loading @@ -35,16 +35,18 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * Class implementing the render session. * Base class for rendering action. * * It provides life-cycle methods to init and stop the rendering. * The most important methods are: * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} * after the rendering. * * A session is a stateful representation of a layout file. It is initialized with data coming * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then * be done on the layout. * * @param <T> the {@link RenderParams} implementation * */ public class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { /** * The current context being rendered. This is set through {@link #acquire(long)} and Loading @@ -65,7 +67,7 @@ public class RenderAction<T extends RenderParams> extends FrameworkResourceIdPro * @param params the RenderParams. This must be a copy that the action can keep * */ public RenderAction(T params) { protected RenderAction(T params) { mParams = params; } Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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.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.BridgeWindow; import com.android.layoutlib.bridge.android.BridgeWindowSession; 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.os.Handler; import android.view.View; import android.view.View.AttachInfo; import android.view.View.MeasureSpec; import android.widget.FrameLayout; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; /** * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}. * * The class only provides a simple {@link #render()} method, but the full life-cycle of the * action must be respected. * * @see RenderAction * */ public class RenderDrawable extends RenderAction<DrawableParams> { public RenderDrawable(DrawableParams params) { super(new DrawableParams(params)); } public Result render() { checkLock(); try { // get the drawable resource value DrawableParams params = getParams(); 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.setBackgroundDrawable(d); // set the AttachInfo on the root view. AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(), new Handler(), null); info.mHasWindowFocus = true; info.mWindowVisibility = View.VISIBLE; info.mInTouchMode = false; // this is so that we can display selections. info.mHardwareAccelerated = false; content.dispatchAttachedToWindow(info, 0); // measure int w = params.getScreenWidth(); int h = params.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 content.mAttachInfo.mTreeObserver.dispatchOnPreDraw(); // 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*/, params.getDensity()); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); canvas.setDensity(params.getDensity().getDpiValue()); // and draw content.draw(canvas); return Status.SUCCESS.createResult(image); } catch (IOException e) { return ERROR_UNKNOWN.createResult(e.getMessage(), e); } } protected BufferedImage getImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D gc = image.createGraphics(); gc.setComposite(AlphaComposite.Src); gc.setColor(new Color(0x00000000, true)); gc.fillRect(0, 0, w, h); // done gc.dispose(); return image; } } Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +29 −0 Original line number Diff line number Diff line Loading @@ -20,12 +20,14 @@ import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN; import static com.android.ide.common.rendering.api.Result.Status.SUCCESS; import com.android.ide.common.rendering.api.Capability; import com.android.ide.common.rendering.api.DrawableParams; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.SessionParams; import com.android.layoutlib.bridge.android.BridgeAssetManager; import com.android.layoutlib.bridge.impl.FontLoader; import com.android.layoutlib.bridge.impl.RenderDrawable; import com.android.layoutlib.bridge.impl.RenderSessionImpl; import com.android.ninepatch.NinePatchChunk; import com.android.resources.ResourceType; Loading Loading @@ -331,6 +333,33 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { } } @Override public Result renderDrawable(DrawableParams params) { try { Result lastResult = SUCCESS.createResult(); RenderDrawable action = new RenderDrawable(params); try { prepareThread(); lastResult = action.init(params.getTimeout()); if (lastResult.isSuccess()) { lastResult = action.render(); } } finally { action.release(); cleanupThread(); } return lastResult; } catch (Throwable t) { // get the real cause of the exception. Throwable t2 = t; while (t2.getCause() != null) { t2 = t.getCause(); } return ERROR_UNKNOWN.createResult(t2.getMessage(), t); } } @Override public void clearCaches(Object projectKey) { if (projectKey != null) { Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +8 −6 Original line number Diff line number Diff line Loading @@ -35,16 +35,18 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * Class implementing the render session. * Base class for rendering action. * * It provides life-cycle methods to init and stop the rendering. * The most important methods are: * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()} * after the rendering. * * A session is a stateful representation of a layout file. It is initialized with data coming * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then * be done on the layout. * * @param <T> the {@link RenderParams} implementation * */ public class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider { /** * The current context being rendered. This is set through {@link #acquire(long)} and Loading @@ -65,7 +67,7 @@ public class RenderAction<T extends RenderParams> extends FrameworkResourceIdPro * @param params the RenderParams. This must be a copy that the action can keep * */ public RenderAction(T params) { protected RenderAction(T params) { mParams = params; } Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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.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.BridgeWindow; import com.android.layoutlib.bridge.android.BridgeWindowSession; 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.os.Handler; import android.view.View; import android.view.View.AttachInfo; import android.view.View.MeasureSpec; import android.widget.FrameLayout; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; /** * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}. * * The class only provides a simple {@link #render()} method, but the full life-cycle of the * action must be respected. * * @see RenderAction * */ public class RenderDrawable extends RenderAction<DrawableParams> { public RenderDrawable(DrawableParams params) { super(new DrawableParams(params)); } public Result render() { checkLock(); try { // get the drawable resource value DrawableParams params = getParams(); 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.setBackgroundDrawable(d); // set the AttachInfo on the root view. AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(), new Handler(), null); info.mHasWindowFocus = true; info.mWindowVisibility = View.VISIBLE; info.mInTouchMode = false; // this is so that we can display selections. info.mHardwareAccelerated = false; content.dispatchAttachedToWindow(info, 0); // measure int w = params.getScreenWidth(); int h = params.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 content.mAttachInfo.mTreeObserver.dispatchOnPreDraw(); // 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*/, params.getDensity()); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); canvas.setDensity(params.getDensity().getDpiValue()); // and draw content.draw(canvas); return Status.SUCCESS.createResult(image); } catch (IOException e) { return ERROR_UNKNOWN.createResult(e.getMessage(), e); } } protected BufferedImage getImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D gc = image.createGraphics(); gc.setComposite(AlphaComposite.Src); gc.setColor(new Color(0x00000000, true)); gc.fillRect(0, 0, w, h); // done gc.dispose(); return image; } }