summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2011-02-04 19:02:17 -0800
committerXavier Ducrohet <xav@android.com>2011-02-04 19:30:35 -0800
commitfd18f573280bbbcc549b35b548580a562bd960e2 (patch)
tree6b953264c673b81b00ff17d11239ffcd8fa75dae /tools
parentb0d34f9c99cbd43e8238c5952b19d032f02dd168 (diff)
downloadframeworks_base-fd18f573280bbbcc549b35b548580a562bd960e2.zip
frameworks_base-fd18f573280bbbcc549b35b548580a562bd960e2.tar.gz
frameworks_base-fd18f573280bbbcc549b35b548580a562bd960e2.tar.bz2
LayoutLib: add implementation of Bridge.renderDrawable()
Change-Id: Ic4d96488fd1a2e5b7d24353bebc8fdb24262c1d1
Diffstat (limited to 'tools')
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java29
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java14
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java141
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;
+ }
+
+}