Scale the GUI to fit the screen

With this patch set, if needed, we scale the images during early
boot. TTF support is needed to properly scale the font. No font
scaling is done on the old style fixed width font used in the
console.

Special thanks to _that for figuring out the scaling and blending
function calls to make this possible.

Change-Id: If2f79bef16d6db2e1298bfc3d00c9bcca2bee37a
diff --git a/gui/pages.cpp b/gui/pages.cpp
index 8fef7b4..47e2edd 100644
--- a/gui/pages.cpp
+++ b/gui/pages.cpp
@@ -41,6 +41,7 @@
 #include "../minuitwrp/minui.h"
 #include "../minzip/SysUtil.h"
 #include "../minzip/Zip.h"
+#include "gui.h"
 }
 
 #include "rapidxml.hpp"
@@ -113,6 +114,7 @@
 		value = node->first_attribute("x")->value();
 		DataManager::GetValue(value, value);
 		*x = atol(value.c_str());
+		*x = scale_theme_x(*x);
 		*x += tw_x_offset;
 	}
 
@@ -121,6 +123,7 @@
 		value = node->first_attribute("y")->value();
 		DataManager::GetValue(value, value);
 		*y = atol(value.c_str());
+		*y = scale_theme_y(*y);
 		*y += tw_y_offset;
 	}
 
@@ -129,6 +132,7 @@
 		value = node->first_attribute("w")->value();
 		DataManager::GetValue(value, value);
 		*w = atol(value.c_str());
+		*w = scale_theme_x(*w);
 	}
 
 	if (h && node->first_attribute("h"))
@@ -136,6 +140,7 @@
 		value = node->first_attribute("h")->value();
 		DataManager::GetValue(value, value);
 		*h = atol(value.c_str());
+		*h = scale_theme_y(*h);
 	}
 
 	if (placement && node->first_attribute("placement"))
@@ -581,7 +586,58 @@
 	if (!parent)
 		parent = mDoc.first_node("install");
 
+	set_scale_values(1, 1); // Reset any previous scaling values
+
 	// Now, let's parse the XML
+	LOGINFO("Checking resolution...\n");
+	child = parent->first_node("details");
+	if (child) {
+		xml_node<>* resolution = child->first_node("resolution");
+		if (resolution) {
+			xml_attribute<>* width_attr = resolution->first_attribute("width");
+			xml_attribute<>* height_attr = resolution->first_attribute("height");
+			xml_attribute<>* noscale_attr = resolution->first_attribute("noscaling");
+			if (width_attr && height_attr && !noscale_attr) {
+				int width = atoi(width_attr->value());
+				int height = atoi(height_attr->value());
+				int offx = 0, offy = 0;
+#ifdef TW_ROUND_SCREEN
+				xml_node<>* roundscreen = child->first_node("roundscreen");
+				if (roundscreen) {
+					LOGINFO("TW_ROUND_SCREEN := true, using round screen XML settings.\n");
+					xml_attribute<>* offx_attr = roundscreen->first_attribute("offset_x");
+					xml_attribute<>* offy_attr = roundscreen->first_attribute("offset_y");
+					if (offx_attr) {
+						offx = atoi(offx_attr->value());
+					}
+					if (offy_attr) {
+						offy = atoi(offy_attr->value());
+					}
+				}
+#endif
+				if (width != 0 && height != 0) {
+					float scale_w = ((float)gr_fb_width() - ((float)offx * 2.0)) / (float)width;
+					float scale_h = ((float)gr_fb_height() - ((float)offy * 2.0)) / (float)height;
+#ifdef TW_ROUND_SCREEN
+					float scale_off_w = (float)gr_fb_width() / (float)width;
+					float scale_off_h = (float)gr_fb_height() / (float)height;
+					tw_x_offset = offx * scale_off_w;
+					tw_y_offset = offy * scale_off_h;
+#endif
+					if (scale_w != 1 || scale_h != 1) {
+						LOGINFO("Scaling theme width %fx and height %fx, offsets x: %i y: %i\n", scale_w, scale_h, tw_x_offset, tw_y_offset);
+						set_scale_values(scale_w, scale_h);
+					}
+				}
+			} else {
+				LOGINFO("XML does not contain width and height, no scaling will be applied\n");
+			}
+		} else {
+			LOGINFO("XML contains no resolution tag, no scaling will be applied.\n");
+		}
+	} else {
+		LOGINFO("XML contains no details tag, no scaling will be applied.\n");
+	}
 	LOGINFO("Loading resources...\n");
 	child = parent->first_node("resources");
 	if (child)