diff --git a/Demo/VisualStudio/tinkerbell_static.vcxproj b/Demo/VisualStudio/tinkerbell_static.vcxproj
index 39f77e1..117c95a 100644
--- a/Demo/VisualStudio/tinkerbell_static.vcxproj
+++ b/Demo/VisualStudio/tinkerbell_static.vcxproj
@@ -51,8 +51,10 @@
     <ClCompile Include="..\..\tinkerbell\src\tb_widget_value.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tb_window.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\tb_test.cpp" />
+    <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_color.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_linklist.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_parser.cpp" />
+    <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_px.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_space_allocator.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_style_edit.cpp" />
     <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_tempbuffer.cpp" />
diff --git a/Demo/VisualStudio/tinkerbell_static.vcxproj.filters b/Demo/VisualStudio/tinkerbell_static.vcxproj.filters
index 83b8fa2..aa52bf2 100644
--- a/Demo/VisualStudio/tinkerbell_static.vcxproj.filters
+++ b/Demo/VisualStudio/tinkerbell_static.vcxproj.filters
@@ -177,6 +177,12 @@
     <ClCompile Include="..\..\tinkerbell\src\tb_skin_util.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_color.cpp">
+      <Filter>Source Files\tests</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\tinkerbell\src\tests\test_tb_px.cpp">
+      <Filter>Source Files\tests</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\tinkerbell\src\tb_language.h">
diff --git a/Demo/demo01/ui_resources/test_scrollcontainer.tb.txt b/Demo/demo01/ui_resources/test_scrollcontainer.tb.txt
index 773d913..1a4d4f0 100644
--- a/Demo/demo01/ui_resources/test_scrollcontainer.tb.txt
+++ b/Demo/demo01/ui_resources/test_scrollcontainer.tb.txt
@@ -9,6 +9,17 @@ TBLayout
 		TBLayout
 			position left top
 			axis y
+			TBTextField: text: Buttons with different fonts:
+			TBLayout
+				TBButton
+					text: "Orange"
+					font: name: Orange
+				TBButton
+					text: "Segoe 14"
+					font: size: 14px
+				TBButton
+					text: "Segoe 28"
+					font: size: 28px
 			TBTextField: text: TBButton containing TBSkinImage:
 			TBLayout
 				TBButton
diff --git a/Makefile b/Makefile
index 21bc814..81ccf4d 100644
--- a/Makefile
+++ b/Makefile
@@ -73,6 +73,8 @@ SRC = tinkerbell/src/tb_layout.cpp \
       tinkerbell/src/tests/test_tb_parser.cpp \
       tinkerbell/src/tests/test_tb_tempbuffer.cpp \
       tinkerbell/src/tests/test_tb_test.cpp \
+      tinkerbell/src/tests/test_tb_color.cpp \
+      tinkerbell/src/tests/test_tb_px.cpp \
       stb_image/tb_image_loader_stb.cpp \
       tbanimation/Animation.cpp \
       tbanimation/tb_animation.cpp \
diff --git a/tinkerbell/src/tb_widgets_reader.cpp b/tinkerbell/src/tb_widgets_reader.cpp
index 28f2425..8867f29 100644
--- a/tinkerbell/src/tb_widgets_reader.cpp
+++ b/tinkerbell/src/tb_widgets_reader.cpp
@@ -12,6 +12,7 @@
 #include "tb_editfield.h"
 #include "tb_language.h"
 #include "parser/TBNodeTree.h"
+#include "tb_font_renderer.h"
 
 namespace tinkerbell {
 
@@ -371,8 +372,24 @@ bool TBWidgetsReader::CreateWidget(TBWidget *target, TBNode *node, WIDGET_Z add_
 		new_widget->SetSkinBg(skin);
 	}
 
+	// Add the new widget to the hiearchy
 	target->GetContentRoot()->AddChild(new_widget, add_child_z);
 
+	// Read the font now when the widget is in the hiearchy so inheritance works.
+	if (TBNode *font = node->GetNode("font"))
+	{
+		TBFontDescription fd = new_widget->GetCalculatedFontDescription();
+		if (const char *size = font->GetValueString("size", nullptr))
+		{
+			TBPx16 px;
+			px.SetFromString(*g_tb_skin->GetDimensionConverter(), size);
+			fd.SetSize(px);
+		}
+		if (const char *name = font->GetValueString("name", nullptr))
+			fd.SetID(name);
+		new_widget->SetFontDescription(fd);
+	}
+
 	// Iterate through all nodes and create widgets
 	for (TBNode *n = node->GetFirstChild(); n; n = n->GetNext())
 		CreateWidget(new_widget, n, wc->add_child_z);
diff --git a/tinkerbell/src/tb_widgets_reader.h b/tinkerbell/src/tb_widgets_reader.h
index 0338a7a..78bf63d 100644
--- a/tinkerbell/src/tb_widgets_reader.h
+++ b/tinkerbell/src/tb_widgets_reader.h
@@ -101,6 +101,8 @@ public:
 	state				TBWidget::SetState		string (disabled)
 	skin				TBWidget::SetSkinBg		TBID (string or int)
 	autofocus			The TBWidget will be focused automatically the first time its TBWindow is activated.
+	font>name			Font name
+	font>size			Font size
 */
 class TBWidgetsReader
 {
diff --git a/tinkerbell/src/tests/test_tb_color.cpp b/tinkerbell/src/tests/test_tb_color.cpp
new file mode 100644
index 0000000..1636e30
--- /dev/null
+++ b/tinkerbell/src/tests/test_tb_color.cpp
@@ -0,0 +1,62 @@
+// ================================================================================
+// == This file is a part of TinkerBell UI Toolkit. (C) 2011-2012, Emil Seger�s  ==
+// ==                   See tinkerbell.h for more information.                   ==
+// ================================================================================
+
+#include "tb_test.h"
+#include "tinkerbell.h"
+
+#ifdef TB_UNIT_TESTING
+
+using namespace tinkerbell;
+
+TB_TEST_GROUP(tb_color)
+{
+	TB_TEST(set_from_string_rrggbbaa)
+	{
+		TBColor col;
+		col.SetFromString("#11223344", 9);
+		TB_VERIFY(col.r == 0x11);
+		TB_VERIFY(col.g == 0x22);
+		TB_VERIFY(col.b == 0x33);
+		TB_VERIFY(col.a == 0x44);
+	}
+	TB_TEST(set_from_string_rrggbb)
+	{
+		TBColor col;
+		col.SetFromString("#112233", 7);
+		TB_VERIFY(col.r == 0x11);
+		TB_VERIFY(col.g == 0x22);
+		TB_VERIFY(col.b == 0x33);
+		TB_VERIFY(col.a == 0xff);
+	}
+	TB_TEST(set_from_string_rgba)
+	{
+		TBColor col;
+		col.SetFromString("#1234", 5);
+		TB_VERIFY(col.r == 0x11);
+		TB_VERIFY(col.g == 0x22);
+		TB_VERIFY(col.b == 0x33);
+		TB_VERIFY(col.a == 0x44);
+	}
+	TB_TEST(set_from_string_rgb)
+	{
+		TBColor col;
+		col.SetFromString("#123", 4);
+		TB_VERIFY(col.r == 0x11);
+		TB_VERIFY(col.g == 0x22);
+		TB_VERIFY(col.b == 0x33);
+		TB_VERIFY(col.a == 0xff);
+	}
+	TB_TEST(set_from_string_invalid)
+	{
+		TBColor col;
+		col.SetFromString("123", 3);
+		TB_VERIFY(col.r == 0x0);
+		TB_VERIFY(col.g == 0x0);
+		TB_VERIFY(col.b == 0x0);
+		TB_VERIFY(col.a == 0xff);
+	}
+}
+
+#endif // TB_UNIT_TESTING
diff --git a/tinkerbell/src/tests/test_tb_px.cpp b/tinkerbell/src/tests/test_tb_px.cpp
new file mode 100644
index 0000000..5ed91db
--- /dev/null
+++ b/tinkerbell/src/tests/test_tb_px.cpp
@@ -0,0 +1,42 @@
+// ================================================================================
+// == This file is a part of TinkerBell UI Toolkit. (C) 2011-2012, Emil Seger�s  ==
+// ==                   See tinkerbell.h for more information.                   ==
+// ================================================================================
+
+#include "tb_test.h"
+#include "tinkerbell.h"
+
+#ifdef TB_UNIT_TESTING
+
+using namespace tinkerbell;
+
+TB_TEST_GROUP(tb_px)
+{
+	TBDimensionConverter dim_conv;
+
+	TB_TEST(Init)
+	{
+		dim_conv.SetDPI(100, 200);
+	}
+
+	TB_TEST(set_from_string_unspecified)
+	{
+		TBPx px;
+		px.SetFromString(dim_conv, "50");
+		TB_VERIFY(px == 50);
+	}
+	TB_TEST(set_from_string_px)
+	{
+		TBPx px;
+		px.SetFromString(dim_conv, "50px");
+		TB_VERIFY(px == 50);
+	}
+	TB_TEST(set_from_string_dp)
+	{
+		TBPx px;
+		px.SetFromString(dim_conv, "50dp");
+		TB_VERIFY(px == 50 * 2);
+	}
+}
+
+#endif // TB_UNIT_TESTING
diff --git a/tinkerbell/src/tinkerbell.cpp b/tinkerbell/src/tinkerbell.cpp
index 8316b91..abf589f 100644
--- a/tinkerbell/src/tinkerbell.cpp
+++ b/tinkerbell/src/tinkerbell.cpp
@@ -351,6 +351,18 @@ int TBDimensionConverter::DpToPx(int dp) const
 
 // == TBPx ==================================================================================================
 
+void TBPx::SetFromString(const TBDimensionConverter &converter, const char *str)
+{
+	if (!str || !isdigit(*str))
+		return;
+	int len = strlen(str);
+	int val = atoi(str);
+	if (len > 2 && stricmp(str + len - 2, "dp") == 0)
+		px = converter.DpToPx(val);
+	else
+		px = val;
+}
+
 void TBPx::SetDP(const TBDimensionConverter &converter, int dp)
 {
 	px = converter.DpToPx(dp);
diff --git a/tinkerbell/src/tinkerbell.h b/tinkerbell/src/tinkerbell.h
index f0f3d7e..b4e37ce 100644
--- a/tinkerbell/src/tinkerbell.h
+++ b/tinkerbell/src/tinkerbell.h
@@ -317,7 +317,7 @@ public:
 		Pixel value:					"1", "1px"
 		Device independent point:		"1dp"
 		*/
-	// void SetFromString(const TBDimensionConverter &converter, const char *str, int len);
+	void SetFromString(const TBDimensionConverter &converter, const char *str);
 
 	/** Set the pixel value from a device independant point. */
 	void SetDP(const TBDimensionConverter &converter, int dp);