aknlayoutcompiler/src/LayScale.cpp
changeset 0 f58d6ec98e88
child 1 b700e12870ca
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/aknlayoutcompiler/src/LayScale.cpp	Thu Dec 17 09:14:18 2009 +0200
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+
+// disable "identifier was truncated to '255' characters in the browser information" warning
+#pragma warning (disable:4786)
+
+#include "LayScale.h"
+#include "LayoutParse.h"
+#include "LayoutCompilerErr.h"
+#include <cdlcompilertoolkit/cdltkprocess.h>
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+#include "LayoutWriter.h"
+
+typedef LayoutProcessArgsErr<LayoutScale> LayoutScaleArgsErr;
+
+
+int LayoutScale::Process(const vector<string>& args)
+	{
+	if (args.size() != 8)
+		throw LayoutScaleArgsErr();
+
+	auto_ptr<TLayParseLayout> sourceLayout(TLayParseLayout::Parse(args[2]));
+	int sourceWidth = CdlTkUtil::ParseInt(args[3]);
+	int sourceHeight = CdlTkUtil::ParseInt(args[4]);
+
+	string destLayout = args[5];
+	int destWidth = CdlTkUtil::ParseInt(args[6]);
+	int destHeight = CdlTkUtil::ParseInt(args[7]);
+
+	LayoutScale scale(*sourceLayout, sourceWidth, sourceHeight, destLayout, destWidth, destHeight);
+	scale.Run();
+
+	return 0;
+	}
+
+void LayoutScale::ShowHelp(ostream& stream)
+	{
+	stream << "LayScale <sourceLayout> <sourceWidth> <sourceHeight> <destLayout> <destWidth> <destHeight>" << endl;
+	stream << "  This performs an arithmetic scaling on all dimensional values in a layout." << endl;
+	stream << "  This will not produce a pixel perfect scaling effect due to rounding errors," << endl;
+	stream << "  however it may be sufficient for prototyping and demonstration purposes." << endl;
+	}
+
+LayoutScale::LayoutScale(TLayout& aSourceLayout, int aSourceWidth, int aSourceHeight, const string& aDestLayoutName, int aDestWidth, int aDestHeight)
+:	iLayout(aSourceLayout),
+	iSourceWidth(aSourceWidth),
+	iSourceHeight(aSourceHeight),
+	iDestLayoutName(aDestLayoutName),
+	iDestWidth(aDestWidth),
+	iDestHeight(aDestHeight)
+	{
+	}
+
+void LayoutScale::Run()
+	{
+	RescaleLayout();
+	WriteLayout();
+	}
+
+const string KHoriz = "lrW";
+const string KVert = "tbBH";
+const string KFont = "Font";
+const string KScaledSuffix = "_Scaled";
+
+void LayoutScale::RescaleLayout()
+	{
+	for (TLayout::iterator pTab = iLayout.begin(); pTab != iLayout.end(); ++pTab)
+		{
+		TLayoutTable& table = **pTab;
+		for (TLayoutTable::iterator pLine = table.begin(); pLine != table.end(); ++pLine)
+			{
+			TLayoutLine& line = **pLine;
+			for (TLayoutLine::iterator pCell = line.begin(); pCell != line.end(); ++pCell)
+				{
+				const string& cellName = pCell->first;
+				TValues& values = pCell->second;
+                if ( cellName == KFont)
+                    {
+				    for (TValues::iterator pVal = values.begin(); pVal != values.end(); ++pVal)
+					    {
+					    TagScaledToken(*pVal);
+					    }                   
+                    }
+                else
+                    {
+   				    TScale dir = EHoriz;
+				    if (KVert.find(cellName) != string::npos)
+				        dir = EVert;
+				    else if (KHoriz.find(cellName) == string::npos)
+				        continue;
+
+				    for (TValues::iterator pVal = values.begin(); pVal != values.end(); ++pVal)
+					    {
+					    RescaleValue(*pVal, dir);
+					    }
+                    }
+				}
+			}
+		}
+	}
+
+void LayoutScale::RescaleValue(string& aVal, TScale aDir)
+	{
+	// find all numbers in this value and rescale them, copy non-numeric text directly.
+	string result;
+	string num;
+	int count = aVal.size();
+	for (int pos = 0; pos < count; pos++)
+		{
+		char c = aVal[pos];
+		if (CdlTkUtil::IsNumeric(c))
+			{
+			num += c;
+			}
+		else
+			{
+			result += RescaleNum(num, aDir);
+			num = "";
+			result += c;
+			}
+		}
+	result += RescaleNum(num, aDir);
+	aVal = result;
+	}
+
+void LayoutScale::TagScaledToken(string& aToken)
+	{
+	string result(aToken);
+	result += KScaledSuffix;
+	aToken = result;
+	}
+
+string LayoutScale::RescaleNum(string& aNum, TScale aDir)
+	{
+	if (aNum.empty())
+		return aNum;
+
+	int num = CdlTkUtil::ParseInt(aNum);
+	if (aDir == EHoriz)
+		num = Scale(num, iDestWidth, iSourceWidth);
+	else
+		num = Scale(num, iDestHeight, iSourceHeight);
+	return CdlTkUtil::IntToString(num);
+	}
+
+void LayoutScale::WriteLayout()
+	{
+	TLayoutWriter writer(iLayout, iDestLayoutName);
+	writer.Write("");
+	}
+
+int LayoutScale::Scale(int aNumber, int aNumerator, int aDenominator)
+	{
+	// round to nearest whole number, rounding up on .5
+	int num = (aNumber * aNumerator) / aDenominator;		// rounded down
+	int remainder = (aNumber * aNumerator) % aDenominator;	// remainder
+	
+	if ((remainder*2) >= aDenominator)
+		num++;				// round up if remainder >= half
+
+	return num;
+	}
+
+