Deals with translation and scaling in layoutlib

Layoutlib now correctly interprets the translation and scaling
xml attributes of views, by implementing what the Android platform
does in native code.

Change-Id: Ie8465f40ef4508d3c31796200800f12cb8f883a4
diff --git a/bridge/src/android/view/RenderNode_Delegate.java b/bridge/src/android/view/RenderNode_Delegate.java
index d62d4e1..1465f50 100644
--- a/bridge/src/android/view/RenderNode_Delegate.java
+++ b/bridge/src/android/view/RenderNode_Delegate.java
@@ -38,10 +38,15 @@
 
 
     private float mLift;
+    private float mTranslationX;
+    private float mTranslationY;
+    private float mTranslationZ;
     private float mRotation;
+    private float mScaleX = 1;
+    private float mScaleY = 1;
     private float mPivotX;
     private float mPivotY;
-    private boolean mPivotExplicitelySet;
+    private boolean mPivotExplicitlySet;
     private int mLeft;
     private int mRight;
     private int mTop;
@@ -81,6 +86,63 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationX != translationX) {
+            delegate.mTranslationX = translationX;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationX;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationY != translationY) {
+            delegate.mTranslationY = translationY;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationY;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationZ != translationZ) {
+            delegate.mTranslationZ = translationZ;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationZ(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationZ;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
     /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
         if (delegate != null && delegate.mRotation != rotation) {
@@ -103,8 +165,17 @@
     /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
         outMatrix.reset();
         if (renderNode != null) {
-            outMatrix.preRotate(renderNode.getRotation(), renderNode.getPivotX(),
-                    renderNode.getPivotY());
+            float rotation = renderNode.getRotation();
+            float translationX = renderNode.getTranslationX();
+            float translationY = renderNode.getTranslationY();
+            float pivotX = renderNode.getPivotX();
+            float pivotY = renderNode.getPivotY();
+            float scaleX = renderNode.getScaleX();
+            float scaleY = renderNode.getScaleY();
+
+            outMatrix.setTranslate(translationX, translationY);
+            outMatrix.preRotate(rotation, pivotX, pivotY);
+            outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
         }
     }
 
@@ -166,18 +237,15 @@
     @LayoutlibDelegate
     /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mPivotExplicitelySet;
-        }
-        return false;
+        return delegate != null && delegate.mPivotExplicitlySet;
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mPivotX != pivotX) {
+        if (delegate != null) {
             delegate.mPivotX = pivotX;
-            delegate.mPivotExplicitelySet = true;
+            delegate.mPivotExplicitlySet = true;
             return true;
         }
         return false;
@@ -187,7 +255,7 @@
     /*package*/ static float nGetPivotX(long renderNode) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
         if (delegate != null) {
-            if (delegate.mPivotExplicitelySet) {
+            if (delegate.mPivotExplicitlySet) {
                 return delegate.mPivotX;
             } else {
                 return (delegate.mRight - delegate.mLeft) / 2.0f;
@@ -199,9 +267,9 @@
     @LayoutlibDelegate
     /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mPivotY != pivotY) {
+        if (delegate != null) {
             delegate.mPivotY = pivotY;
-            delegate.mPivotExplicitelySet = true;
+            delegate.mPivotExplicitlySet = true;
             return true;
         }
         return false;
@@ -211,7 +279,7 @@
     /*package*/ static float nGetPivotY(long renderNode) {
         RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
         if (delegate != null) {
-            if (delegate.mPivotExplicitelySet) {
+            if (delegate.mPivotExplicitlySet) {
                 return delegate.mPivotY;
             } else {
                 return (delegate.mBottom - delegate.mTop) / 2.0f;
@@ -219,4 +287,42 @@
         }
         return 0f;
     }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mScaleX != scaleX) {
+            delegate.mScaleX = scaleX;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetScaleX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mScaleX;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mScaleY != scaleY) {
+            delegate.mScaleY = scaleY;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetScaleY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mScaleY;
+        }
+        return 0f;
+    }
 }