Loading tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +19 −7 Original line number Diff line number Diff line Loading @@ -92,13 +92,6 @@ public class Canvas_Delegate { return mGraphicsStack.peek(); } /** * Disposes of the {@link Graphics2D} stack. */ public void dispose() { } // ---- native methods ---- /*package*/ static boolean isOpaque(Canvas thisCanvas) { Loading Loading @@ -985,6 +978,16 @@ public class Canvas_Delegate { } /*package*/ static void finalizer(int nativeCanvas) { // get the delegate from the native int so that it can be disposed. Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas); if (canvasDelegate == null) { assert false; return; } canvasDelegate.dispose(); // remove it from the manager. sManager.removeDelegate(nativeCanvas); } Loading @@ -997,6 +1000,15 @@ public class Canvas_Delegate { private Canvas_Delegate() { } /** * Disposes of the {@link Graphics2D} stack. */ private void dispose() { while (mGraphicsStack.size() > 0) { mGraphicsStack.pop().dispose(); } } private void setBitmap(BufferedImage image) { mBufferedImage = image; mGraphicsStack.push(mBufferedImage.createGraphics()); Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +28 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.tools.layoutlib.create.OverrideMethod; import android.graphics.Bitmap; import android.graphics.Typeface_Delegate; import android.os.Looper; import android.util.Finalizers; import java.lang.ref.SoftReference; Loading Loading @@ -294,7 +295,7 @@ public final class Bridge extends LayoutBridge { SceneResult lastResult = SceneResult.SUCCESS; LayoutSceneImpl scene = new LayoutSceneImpl(params); try { scene.prepareThread(); prepareThread(); lastResult = scene.init(params.getTimeout()); if (lastResult == SceneResult.SUCCESS) { lastResult = scene.inflate(); Loading @@ -304,7 +305,7 @@ public final class Bridge extends LayoutBridge { } } finally { scene.release(); scene.cleanupThread(); cleanupThread(); } return new BridgeLayoutScene(scene, lastResult); Loading Loading @@ -338,6 +339,31 @@ public final class Bridge extends LayoutBridge { return sLock; } /** * Prepares the current thread for rendering. * * Note that while this can be called several time, the first call to {@link #cleanupThread()} * will do the clean-up, and make the thread unable to do further scene actions. */ public static void prepareThread() { // we need to make sure the Looper has been initialized for this thread. // this is required for View that creates Handler objects. if (Looper.myLooper() == null) { Looper.prepare(); } } /** * Cleans up thread-specific data. After this, the thread cannot be used for scene actions. * <p> * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single * call to this will prevent the thread from doing further scene actions */ public static void cleanupThread() { // clean up the looper Looper.sThreadLocal.remove(); } /** * Returns details of a framework resource from its integer value. * @param value the integer value Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java +10 −10 Original line number Diff line number Diff line Loading @@ -64,14 +64,14 @@ public class BridgeLayoutScene extends LayoutScene { @Override public SceneResult render(long timeout) { try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(timeout); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.render(); } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -81,7 +81,7 @@ public class BridgeLayoutScene extends LayoutScene { public SceneResult animate(Object targetObject, String animationName, boolean isFrameworkAnimation, IAnimationListener listener) { try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.animate(targetObject, animationName, isFrameworkAnimation, Loading @@ -89,7 +89,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -106,7 +106,7 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.insertChild((ViewGroup) parentView, childXml, Loading @@ -114,7 +114,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -135,7 +135,7 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView, Loading @@ -143,7 +143,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -156,14 +156,14 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.removeChild((View) childView, listener); } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.impl; import com.android.layoutlib.api.SceneResult; import com.android.layoutlib.api.LayoutScene.IAnimationListener; import com.android.layoutlib.bridge.Bridge; import android.animation.Animator; import android.animation.ValueAnimator; Loading Loading @@ -57,7 +58,7 @@ public class AnimationThread extends Thread { @Override public void run() { mScene.prepareThread(); Bridge.prepareThread(); try { Handler_Delegate.setCallback(new IHandlerCallback() { public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) { Loading Loading @@ -115,7 +116,7 @@ public class AnimationThread extends Thread { mListener.done(SceneResult.SUCCESS); } finally { Handler_Delegate.setCallback(null); mScene.cleanupThread(); Bridge.cleanupThread(); } } } tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java +102 −89 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.graphics.Canvas; import android.graphics.Canvas_Delegate; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; Loading Loading @@ -104,6 +103,9 @@ public class LayoutSceneImpl { private int mScreenOffset; private IResourceValue mWindowBackground; private FrameLayout mViewRoot; private Canvas mCanvas; private int mMeasuredScreenWidth = -1; private int mMeasuredScreenHeight = -1; // information being returned through the API private BufferedImage mImage; Loading Loading @@ -201,31 +203,6 @@ public class LayoutSceneImpl { return SceneResult.SUCCESS; } /** * Prepares the current thread for rendering. * * Note that while this can be called several time, the first call to {@link #cleanupThread()} * will do the clean-up, and make the thread unable to do further scene actions. */ public void prepareThread() { // we need to make sure the Looper has been initialized for this thread. // this is required for View that creates Handler objects. if (Looper.myLooper() == null) { Looper.prepare(); } } /** * Cleans up thread-specific data. After this, the thread cannot be used for scene actions. * <p> * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single * call to this will prevent the thread from doing further scene actions */ public void cleanupThread() { // clean up the looper Looper.sThreadLocal.remove(); } /** * Prepares the scene for action. * <p> Loading Loading @@ -389,30 +366,35 @@ public class LayoutSceneImpl { * * @throws IllegalStateException if the current context is different than the one owned by * the scene, or if {@link #acquire(long)} was not called. * * @see SceneParams#getRenderingMode() */ public SceneResult render() { checkLock(); try { long current = System.currentTimeMillis(); if (mViewRoot == null) { return new SceneResult(SceneStatus.ERROR_NOT_INFLATED); } // measure the views int w_spec, h_spec; int renderScreenWidth = mParams.getScreenWidth(); int renderScreenHeight = mParams.getScreenHeight(); RenderingMode renderingMode = mParams.getRenderingMode(); // only do the screen measure when needed. boolean newRenderSize = false; if (mMeasuredScreenWidth == -1) { newRenderSize = true; mMeasuredScreenWidth = mParams.getScreenWidth(); mMeasuredScreenHeight = mParams.getScreenHeight(); if (renderingMode != RenderingMode.NORMAL) { // measure the full size needed by the layout. w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, renderingMode.isHorizExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset, h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, renderingMode.isVertExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); Loading @@ -420,43 +402,45 @@ public class LayoutSceneImpl { if (renderingMode.isHorizExpand()) { int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth(); if (neededWidth > renderScreenWidth) { renderScreenWidth = neededWidth; if (neededWidth > mMeasuredScreenWidth) { mMeasuredScreenWidth = neededWidth; } } if (renderingMode.isVertExpand()) { int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight(); if (neededHeight > renderScreenHeight - mScreenOffset) { renderScreenHeight = neededHeight + mScreenOffset; if (neededHeight > mMeasuredScreenHeight - mScreenOffset) { mMeasuredScreenHeight = neededHeight + mScreenOffset; } } } } // remeasure with the size we need // This must always be done before the call to layout w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset, w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, MeasureSpec.EXACTLY); mViewRoot.measure(w_spec, h_spec); // now do the layout. mViewRoot.layout(0, mScreenOffset, renderScreenWidth, renderScreenHeight); mViewRoot.layout(0, mScreenOffset, mMeasuredScreenWidth, mMeasuredScreenHeight); // draw the views // create the BufferedImage into which the layout will be rendered. if (newRenderSize || mCanvas == null) { if (mParams.getImageFactory() != null) { mImage = mParams.getImageFactory().getImage(renderScreenWidth, renderScreenHeight - mScreenOffset); mImage = mParams.getImageFactory().getImage(mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); } else { mImage = new BufferedImage(renderScreenWidth, renderScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB); mImage = new BufferedImage(mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB); } if (mParams.isCustomBackgroundEnabled()) { Graphics2D gc = mImage.createGraphics(); gc.setColor(new Color(mParams.getCustomBackgroundColor(), true)); gc.fillRect(0, 0, renderScreenWidth, renderScreenHeight - mScreenOffset); gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); gc.dispose(); } Loading @@ -466,19 +450,23 @@ public class LayoutSceneImpl { Density.getEnum(mParams.getDensity())); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); canvas.setDensity(mParams.getDensity()); mCanvas = new Canvas(bitmap); mCanvas.setDensity(mParams.getDensity()); } // to set the logger, get the native delegate Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas); Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(mCanvas); canvasDelegate.setLogger(mParams.getLogger()); mViewRoot.draw(canvas); canvasDelegate.dispose(); long preDrawTime = System.currentTimeMillis(); mViewRoot.draw(mCanvas); long drawTime = System.currentTimeMillis(); mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext); System.out.println("rendering (ms): " + (System.currentTimeMillis() - current)); System.out.println(String.format("rendering (ms): %03d", drawTime - preDrawTime)); // success! return SceneResult.SUCCESS; Loading Loading @@ -567,7 +555,14 @@ public class LayoutSceneImpl { View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); // add it to the parentView in the correct location try { parentView.addView(child, index); } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading @@ -581,6 +576,7 @@ public class LayoutSceneImpl { throw new IllegalArgumentException("beforeSibling not in parentView"); } try { ViewParent parent = childView.getParent(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; Loading @@ -589,6 +585,12 @@ public class LayoutSceneImpl { // add it to the parentView in the correct location parentView.addView(childView, index); } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading @@ -596,11 +598,18 @@ public class LayoutSceneImpl { public SceneResult removeChild(View childView, IAnimationListener listener) { checkLock(); try { ViewParent parent = childView.getParent(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; parentGroup.removeView(childView); } } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading Loading @@ -971,6 +980,10 @@ public class LayoutSceneImpl { return result; } private void invalidateRenderingSize() { mMeasuredScreenWidth = mMeasuredScreenHeight = -1; } public BufferedImage getImage() { return mImage; } Loading Loading
tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +19 −7 Original line number Diff line number Diff line Loading @@ -92,13 +92,6 @@ public class Canvas_Delegate { return mGraphicsStack.peek(); } /** * Disposes of the {@link Graphics2D} stack. */ public void dispose() { } // ---- native methods ---- /*package*/ static boolean isOpaque(Canvas thisCanvas) { Loading Loading @@ -985,6 +978,16 @@ public class Canvas_Delegate { } /*package*/ static void finalizer(int nativeCanvas) { // get the delegate from the native int so that it can be disposed. Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas); if (canvasDelegate == null) { assert false; return; } canvasDelegate.dispose(); // remove it from the manager. sManager.removeDelegate(nativeCanvas); } Loading @@ -997,6 +1000,15 @@ public class Canvas_Delegate { private Canvas_Delegate() { } /** * Disposes of the {@link Graphics2D} stack. */ private void dispose() { while (mGraphicsStack.size() > 0) { mGraphicsStack.pop().dispose(); } } private void setBitmap(BufferedImage image) { mBufferedImage = image; mGraphicsStack.push(mBufferedImage.createGraphics()); Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +28 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import com.android.tools.layoutlib.create.OverrideMethod; import android.graphics.Bitmap; import android.graphics.Typeface_Delegate; import android.os.Looper; import android.util.Finalizers; import java.lang.ref.SoftReference; Loading Loading @@ -294,7 +295,7 @@ public final class Bridge extends LayoutBridge { SceneResult lastResult = SceneResult.SUCCESS; LayoutSceneImpl scene = new LayoutSceneImpl(params); try { scene.prepareThread(); prepareThread(); lastResult = scene.init(params.getTimeout()); if (lastResult == SceneResult.SUCCESS) { lastResult = scene.inflate(); Loading @@ -304,7 +305,7 @@ public final class Bridge extends LayoutBridge { } } finally { scene.release(); scene.cleanupThread(); cleanupThread(); } return new BridgeLayoutScene(scene, lastResult); Loading Loading @@ -338,6 +339,31 @@ public final class Bridge extends LayoutBridge { return sLock; } /** * Prepares the current thread for rendering. * * Note that while this can be called several time, the first call to {@link #cleanupThread()} * will do the clean-up, and make the thread unable to do further scene actions. */ public static void prepareThread() { // we need to make sure the Looper has been initialized for this thread. // this is required for View that creates Handler objects. if (Looper.myLooper() == null) { Looper.prepare(); } } /** * Cleans up thread-specific data. After this, the thread cannot be used for scene actions. * <p> * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single * call to this will prevent the thread from doing further scene actions */ public static void cleanupThread() { // clean up the looper Looper.sThreadLocal.remove(); } /** * Returns details of a framework resource from its integer value. * @param value the integer value Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java +10 −10 Original line number Diff line number Diff line Loading @@ -64,14 +64,14 @@ public class BridgeLayoutScene extends LayoutScene { @Override public SceneResult render(long timeout) { try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(timeout); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.render(); } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -81,7 +81,7 @@ public class BridgeLayoutScene extends LayoutScene { public SceneResult animate(Object targetObject, String animationName, boolean isFrameworkAnimation, IAnimationListener listener) { try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.animate(targetObject, animationName, isFrameworkAnimation, Loading @@ -89,7 +89,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -106,7 +106,7 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.insertChild((ViewGroup) parentView, childXml, Loading @@ -114,7 +114,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -135,7 +135,7 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView, Loading @@ -143,7 +143,7 @@ public class BridgeLayoutScene extends LayoutScene { } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading @@ -156,14 +156,14 @@ public class BridgeLayoutScene extends LayoutScene { } try { mScene.prepareThread(); Bridge.prepareThread(); mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT); if (mLastResult == SceneResult.SUCCESS) { mLastResult = mScene.removeChild((View) childView, listener); } } finally { mScene.release(); mScene.cleanupThread(); Bridge.cleanupThread(); } return mLastResult; Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.impl; import com.android.layoutlib.api.SceneResult; import com.android.layoutlib.api.LayoutScene.IAnimationListener; import com.android.layoutlib.bridge.Bridge; import android.animation.Animator; import android.animation.ValueAnimator; Loading Loading @@ -57,7 +58,7 @@ public class AnimationThread extends Thread { @Override public void run() { mScene.prepareThread(); Bridge.prepareThread(); try { Handler_Delegate.setCallback(new IHandlerCallback() { public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) { Loading Loading @@ -115,7 +116,7 @@ public class AnimationThread extends Thread { mListener.done(SceneResult.SUCCESS); } finally { Handler_Delegate.setCallback(null); mScene.cleanupThread(); Bridge.cleanupThread(); } } }
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java +102 −89 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.graphics.Canvas; import android.graphics.Canvas_Delegate; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.View; Loading Loading @@ -104,6 +103,9 @@ public class LayoutSceneImpl { private int mScreenOffset; private IResourceValue mWindowBackground; private FrameLayout mViewRoot; private Canvas mCanvas; private int mMeasuredScreenWidth = -1; private int mMeasuredScreenHeight = -1; // information being returned through the API private BufferedImage mImage; Loading Loading @@ -201,31 +203,6 @@ public class LayoutSceneImpl { return SceneResult.SUCCESS; } /** * Prepares the current thread for rendering. * * Note that while this can be called several time, the first call to {@link #cleanupThread()} * will do the clean-up, and make the thread unable to do further scene actions. */ public void prepareThread() { // we need to make sure the Looper has been initialized for this thread. // this is required for View that creates Handler objects. if (Looper.myLooper() == null) { Looper.prepare(); } } /** * Cleans up thread-specific data. After this, the thread cannot be used for scene actions. * <p> * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single * call to this will prevent the thread from doing further scene actions */ public void cleanupThread() { // clean up the looper Looper.sThreadLocal.remove(); } /** * Prepares the scene for action. * <p> Loading Loading @@ -389,30 +366,35 @@ public class LayoutSceneImpl { * * @throws IllegalStateException if the current context is different than the one owned by * the scene, or if {@link #acquire(long)} was not called. * * @see SceneParams#getRenderingMode() */ public SceneResult render() { checkLock(); try { long current = System.currentTimeMillis(); if (mViewRoot == null) { return new SceneResult(SceneStatus.ERROR_NOT_INFLATED); } // measure the views int w_spec, h_spec; int renderScreenWidth = mParams.getScreenWidth(); int renderScreenHeight = mParams.getScreenHeight(); RenderingMode renderingMode = mParams.getRenderingMode(); // only do the screen measure when needed. boolean newRenderSize = false; if (mMeasuredScreenWidth == -1) { newRenderSize = true; mMeasuredScreenWidth = mParams.getScreenWidth(); mMeasuredScreenHeight = mParams.getScreenHeight(); if (renderingMode != RenderingMode.NORMAL) { // measure the full size needed by the layout. w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, renderingMode.isHorizExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset, h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, renderingMode.isVertExpand() ? MeasureSpec.UNSPECIFIED // this lets us know the actual needed size : MeasureSpec.EXACTLY); Loading @@ -420,43 +402,45 @@ public class LayoutSceneImpl { if (renderingMode.isHorizExpand()) { int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth(); if (neededWidth > renderScreenWidth) { renderScreenWidth = neededWidth; if (neededWidth > mMeasuredScreenWidth) { mMeasuredScreenWidth = neededWidth; } } if (renderingMode.isVertExpand()) { int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight(); if (neededHeight > renderScreenHeight - mScreenOffset) { renderScreenHeight = neededHeight + mScreenOffset; if (neededHeight > mMeasuredScreenHeight - mScreenOffset) { mMeasuredScreenHeight = neededHeight + mScreenOffset; } } } } // remeasure with the size we need // This must always be done before the call to layout w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset, w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY); h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight - mScreenOffset, MeasureSpec.EXACTLY); mViewRoot.measure(w_spec, h_spec); // now do the layout. mViewRoot.layout(0, mScreenOffset, renderScreenWidth, renderScreenHeight); mViewRoot.layout(0, mScreenOffset, mMeasuredScreenWidth, mMeasuredScreenHeight); // draw the views // create the BufferedImage into which the layout will be rendered. if (newRenderSize || mCanvas == null) { if (mParams.getImageFactory() != null) { mImage = mParams.getImageFactory().getImage(renderScreenWidth, renderScreenHeight - mScreenOffset); mImage = mParams.getImageFactory().getImage(mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); } else { mImage = new BufferedImage(renderScreenWidth, renderScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB); mImage = new BufferedImage(mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset, BufferedImage.TYPE_INT_ARGB); } if (mParams.isCustomBackgroundEnabled()) { Graphics2D gc = mImage.createGraphics(); gc.setColor(new Color(mParams.getCustomBackgroundColor(), true)); gc.fillRect(0, 0, renderScreenWidth, renderScreenHeight - mScreenOffset); gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight - mScreenOffset); gc.dispose(); } Loading @@ -466,19 +450,23 @@ public class LayoutSceneImpl { Density.getEnum(mParams.getDensity())); // create a Canvas around the Android bitmap Canvas canvas = new Canvas(bitmap); canvas.setDensity(mParams.getDensity()); mCanvas = new Canvas(bitmap); mCanvas.setDensity(mParams.getDensity()); } // to set the logger, get the native delegate Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas); Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(mCanvas); canvasDelegate.setLogger(mParams.getLogger()); mViewRoot.draw(canvas); canvasDelegate.dispose(); long preDrawTime = System.currentTimeMillis(); mViewRoot.draw(mCanvas); long drawTime = System.currentTimeMillis(); mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext); System.out.println("rendering (ms): " + (System.currentTimeMillis() - current)); System.out.println(String.format("rendering (ms): %03d", drawTime - preDrawTime)); // success! return SceneResult.SUCCESS; Loading Loading @@ -567,7 +555,14 @@ public class LayoutSceneImpl { View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); // add it to the parentView in the correct location try { parentView.addView(child, index); } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading @@ -581,6 +576,7 @@ public class LayoutSceneImpl { throw new IllegalArgumentException("beforeSibling not in parentView"); } try { ViewParent parent = childView.getParent(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; Loading @@ -589,6 +585,12 @@ public class LayoutSceneImpl { // add it to the parentView in the correct location parentView.addView(childView, index); } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading @@ -596,11 +598,18 @@ public class LayoutSceneImpl { public SceneResult removeChild(View childView, IAnimationListener listener) { checkLock(); try { ViewParent parent = childView.getParent(); if (parent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) parent; parentGroup.removeView(childView); } } catch (UnsupportedOperationException e) { // looks like this is a view class that doesn't support children manipulation! return new SceneResult(SceneStatus.ERROR_VIEWGROUP_NO_CHILDREN); } invalidateRenderingSize(); return render(); } Loading Loading @@ -971,6 +980,10 @@ public class LayoutSceneImpl { return result; } private void invalidateRenderingSize() { mMeasuredScreenWidth = mMeasuredScreenHeight = -1; } public BufferedImage getImage() { return mImage; } Loading