diff options
author | Xavier Ducrohet <xav@android.com> | 2011-02-04 19:33:27 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2011-02-04 19:33:27 -0800 |
commit | 1d009fbd17c52a0f3cdd26582e55abe03b125890 (patch) | |
tree | 4d351aedacce892121714352f0b0b9bafcbd9b7c /tools | |
parent | 9a5bda875f86b188b501ce7cf73810dd92288251 (diff) | |
parent | 35064e5e3a04bda6211166630ccd49d522a8bd92 (diff) | |
download | frameworks_base-1d009fbd17c52a0f3cdd26582e55abe03b125890.zip frameworks_base-1d009fbd17c52a0f3cdd26582e55abe03b125890.tar.gz frameworks_base-1d009fbd17c52a0f3cdd26582e55abe03b125890.tar.bz2 |
am 35064e5e: Merge "LayoutLib: add implementation of Bridge.renderDrawable()" into honeycomb
* commit '35064e5e3a04bda6211166630ccd49d522a8bd92':
LayoutLib: add implementation of Bridge.renderDrawable()
Diffstat (limited to 'tools')
3 files changed, 178 insertions, 6 deletions
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index dff7ff1..c01962d 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -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; @@ -332,6 +334,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) { sProjectBitmapCache.remove(projectKey); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index 82ac176..8e80c21 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -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 @@ -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; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java new file mode 100644 index 0000000..953d8cf --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java @@ -0,0 +1,141 @@ +/* + * 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; + } + +} |