Adding support for transform components.
diff --git a/Source/Mat2D.cpp b/Source/Mat2D.cpp
index 91a79c4..ae39c27 100644
--- a/Source/Mat2D.cpp
+++ b/Source/Mat2D.cpp
@@ -1,5 +1,6 @@
 #include "Mat2D.hpp"
 #include "Vec2D.hpp"
+#include "TransformComponents.hpp"
 #include <cmath>
 
 using namespace nima;
@@ -77,3 +78,47 @@
 	result[4] = a[4];
 	result[5] = a[5];
 }
+
+void Mat2D::decompose(TransformComponents& result, const Mat2D& m)
+{
+	float m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3];
+
+	float rotation = (float)std::atan2(m1, m0);
+	float denom = m0*m0 + m1*m1;
+	float scaleX = (float)std::sqrt(denom);
+	float scaleY = (m0 * m3 - m2 * m1) / scaleX;
+	float skewX = (float)std::atan2(m0 * m2 + m1 * m3, denom);
+
+	result.x(m[4]);
+	result.y(m[5]);
+	result.scaleX(scaleX);
+	result.scaleY(scaleY);
+	result.rotation(rotation);
+	result.skew(skewX);
+}
+
+void Mat2D::compose(Mat2D& result, const TransformComponents& components)
+{
+	float r = components.rotation();
+
+	if(r != 0.0)
+	{
+		Mat2D::fromRotation(result, r);
+	}
+	else
+	{
+		Mat2D::identity(result);
+	}
+	result[4] = components.x();
+	result[5] = components.y();
+	Vec2D scale;
+	components.scale(scale);
+	Mat2D::scale(result, result, scale);
+
+	float sk = components.skew();
+	if(sk != 0.0)
+	{
+		result[2] = result[0] * sk + result[2];
+		result[3] = result[1] * sk + result[3];
+	}
+}
diff --git a/Source/Mat2D.hpp b/Source/Mat2D.hpp
index 6277944..f2505e6 100644
--- a/Source/Mat2D.hpp
+++ b/Source/Mat2D.hpp
@@ -6,6 +6,7 @@
 namespace nima
 {
 	class Vec2D;
+	class TransformComponents;
 	class Mat2D
 	{
 		private:
@@ -20,11 +21,23 @@
 			float& operator[](std::size_t idx) { return m_Buffer[idx]; }
 			const float& operator[](std::size_t idx) const { return m_Buffer[idx]; }
 
+			static void identity(Mat2D& result)
+			{
+				result[0] = 1.0f;
+				result[1] = 0.0f;
+				result[2] = 0.0f;
+				result[3] = 1.0f;
+				result[4] = 0.0f;
+				result[5] = 0.0f;
+			}
+
 			static void fromRotation(Mat2D& result, float rad);
 			static void scale(Mat2D& result, const Mat2D& mat, const Vec2D& vec);
 			static void multiply(Mat2D& result, const Mat2D& a, const Mat2D& b);
 			static bool invert(Mat2D& result, const Mat2D& a);
 			static void copy(Mat2D& result, const Mat2D& a);
+			static void decompose(TransformComponents& result, const Mat2D& m);
+			static void compose(Mat2D& result, const TransformComponents& components);
 	};
 
 	inline Mat2D operator*(const Mat2D& a, const Mat2D& b)
diff --git a/Source/TransformComponents.hpp b/Source/TransformComponents.hpp
new file mode 100644
index 0000000..31506c4
--- /dev/null
+++ b/Source/TransformComponents.hpp
@@ -0,0 +1,40 @@
+#ifndef _NIMA_TRANSFORMCOMPONENTS_HPP_
+#define _NIMA_TRANSFORMCOMPONENTS_HPP_
+
+#include <cstddef>
+#include "Vec2D.hpp"
+
+namespace nima
+{
+	class TransformComponents
+	{
+		private:
+			float m_X;
+            float m_Y;
+            float m_ScaleX;
+            float m_ScaleY;
+            float m_Rotation;
+            float m_Skew;
+
+		public:
+			TransformComponents() : m_X(0.0f), m_Y(0.0f), m_ScaleX(1.0f), m_ScaleY(1.0f), m_Rotation(0.0f), m_Skew(0.0f){}
+			TransformComponents(const TransformComponents& copy) : m_X(copy.m_X), m_Y(copy.m_Y), m_ScaleX(copy.m_ScaleX), m_ScaleY(copy.m_ScaleY), m_Rotation(copy.m_Rotation), m_Skew(copy.m_Skew){}
+
+			float x() const { return m_X; }
+            void x(float value) { m_X = value; }
+            float y() const { return m_Y; }
+            void y(float value) { m_Y = value; }
+            float scaleX() const { return m_ScaleX; }
+            void scaleX(float value) { m_ScaleX = value; }
+            float scaleY() const { return m_ScaleY; }
+            void scaleY(float value) { m_ScaleY = value; }
+            float rotation() const { return m_Rotation; }
+            void rotation(float value) { m_Rotation = value; }
+            float skew() const { return m_Skew; }
+            void skew(float value) { m_Skew = value; }
+
+            void translation(Vec2D& result) const { result[0] = m_X; result[1] = m_Y; }
+            void scale(Vec2D& result) const { result[0] = m_ScaleX; result[1] = m_ScaleY; }
+	};
+}
+#endif
\ No newline at end of file