summaryrefslogtreecommitdiff
path: root/libtemplate/templatepixmap.c
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2014-09-27 09:25:14 +0200
committerlouis <louis.braun@gmx.de>2014-09-27 09:25:14 +0200
commitb0509b5182b6e0d04f05e6b3d5676b0d21f51966 (patch)
tree22b302342f22843e0815eb5f516c85f1478cbf0b /libtemplate/templatepixmap.c
downloadvdr-plugin-skindesigner-b0509b5182b6e0d04f05e6b3d5676b0d21f51966.tar.gz
vdr-plugin-skindesigner-b0509b5182b6e0d04f05e6b3d5676b0d21f51966.tar.bz2
initial commit version 0.0.10.0.1
Diffstat (limited to 'libtemplate/templatepixmap.c')
-rw-r--r--libtemplate/templatepixmap.c473
1 files changed, 473 insertions, 0 deletions
diff --git a/libtemplate/templatepixmap.c b/libtemplate/templatepixmap.c
new file mode 100644
index 0000000..8aaa4f3
--- /dev/null
+++ b/libtemplate/templatepixmap.c
@@ -0,0 +1,473 @@
+#include "templatepixmap.h"
+
+using namespace std;
+
+// --- cTemplatePixmap -------------------------------------------------------------
+
+cTemplatePixmap::cTemplatePixmap(void) {
+ parameters = NULL;
+ containerX = 0;
+ containerY = 0;
+ containerWidth = 0;
+ containerHeight = 0;
+ globals = NULL;
+ scrolling = false;
+}
+
+cTemplatePixmap::~cTemplatePixmap() {
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ delete (*it);
+ }
+ if (parameters)
+ delete parameters;
+}
+
+void cTemplatePixmap::SetParameters(vector<pair<string, string> > &params) {
+ parameters = new cTemplateFunction(ftPixmap);
+ parameters->SetGlobals(globals);
+ parameters->SetParameters(params);
+}
+
+void cTemplatePixmap::SetContainer(int x, int y, int w, int h) {
+ containerX = x;
+ containerY = y;
+ containerWidth = w;
+ containerHeight = h;
+}
+
+void cTemplatePixmap::SetWidth(int width) {
+ cString pWidth = cString::sprintf("%d", width);
+ parameters->SetWidthManually(*pWidth);
+}
+
+void cTemplatePixmap::SetHeight(int height) {
+ cString pHeight = cString::sprintf("%d", height);
+ parameters->SetHeightManually(*pHeight);
+}
+
+void cTemplatePixmap::SetX(int x) {
+ parameters->SetXManually(x);
+}
+
+void cTemplatePixmap::SetY(int y) {
+ parameters->SetYManually(y);
+}
+
+void cTemplatePixmap::ClearDynamicParameters(void) {
+ parameters->ClearDynamicParameters();
+}
+
+void cTemplatePixmap::ParseDynamicParameters(map <string,int> *intTokens, bool initFuncs) {
+ parameters->ClearDynamicParameters();
+ parameters->SetIntTokens(intTokens);
+ parameters->ParseParameters();
+ parameters->UnsetIntTokens();
+
+ if (!DoExecute()) {
+ parameters->ClearDynamicParameters();
+ return;
+ }
+
+ if (!initFuncs || !Ready())
+ return;
+
+ int x = parameters->GetNumericParameter(ptX);
+ int y = parameters->GetNumericParameter(ptY);
+ int width = parameters->GetNumericParameter(ptWidth);
+ int height = parameters->GetNumericParameter(ptHeight);
+
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->SetContainer(x, y, width, height);
+ (*func)->CalculateParameters();
+ (*func)->CompleteParameters();
+ if ((*func)->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(*func);
+ if (!loopFunc->Ready()) {
+ loopFunc->SetIntTokens(intTokens);
+ loopFunc->ParseParameters();
+ loopFunc->UnsetIntTokens();
+ }
+ loopFunc->CalculateLoopFuncParameters();
+ }
+ }
+}
+
+void cTemplatePixmap::AddFunction(string name, vector<pair<string, string> > &params) {
+ eFuncType type = ftNone;
+
+ if (!name.compare("fill")) {
+ type = ftFill;
+ } else if (!name.compare("drawtext")) {
+ type = ftDrawText;
+ } else if (!name.compare("drawtextbox")) {
+ type = ftDrawTextBox;
+ } else if (!name.compare("drawimage")) {
+ type = ftDrawImage;
+ } else if (!name.compare("drawrectangle")) {
+ type = ftDrawRectangle;
+ } else if (!name.compare("drawellipse")) {
+ type = ftDrawEllipse;
+ }
+
+ if (type == ftNone) {
+ return;
+ }
+
+ cTemplateFunction *f = new cTemplateFunction(type);
+ f->SetParameters(params);
+ functions.push_back(f);
+}
+
+void cTemplatePixmap::AddLoopFunction(cTemplateLoopFunction *lf) {
+ functions.push_back(lf);
+}
+
+
+bool cTemplatePixmap::CalculateParameters(void) {
+ bool paramsValid = true;
+ //Calculate Pixmap Size
+ parameters->SetContainer(containerX, containerY, containerWidth, containerHeight);
+ parameters->SetGlobals(globals);
+ paramsValid = parameters->CalculateParameters();
+
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ int pixHeight = parameters->GetNumericParameter(ptHeight);
+
+ for (vector<cTemplateFunction*>::iterator func = functions.begin(); func != functions.end(); func++) {
+ (*func)->SetGlobals(globals);
+ if (!Ready())
+ continue;
+ (*func)->SetContainer(0, 0, pixWidth, pixHeight);
+ paramsValid = (*func)->CalculateParameters();
+ (*func)->CompleteParameters();
+ if ((*func)->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(*func);
+ loopFunc->CalculateLoopFuncParameters();
+ }
+ }
+
+ return paramsValid;
+}
+
+void cTemplatePixmap::ClearDynamicFunctionParameters(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ func->ClearDynamicParameters();
+ }
+}
+
+void cTemplatePixmap::ParseDynamicFunctionParameters(map <string,string> *stringTokens, map <string,int> *intTokens) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ bool completelyParsed = true;
+ bool updated = false;
+ while(func = GetNextFunction()) {
+ func->SetStringTokens(stringTokens);
+ func->SetIntTokens(intTokens);
+ bool funcCompletelyParsed = func->ParseParameters();
+ if (!funcCompletelyParsed)
+ completelyParsed = false;
+ if (func->Updated())
+ func->CompleteParameters();
+ func->UnsetIntTokens();
+ func->UnsetStringTokens();
+ }
+
+ if (completelyParsed) {
+ return;
+ }
+
+ ReplaceWidthFunctions();
+ ReplaceHeightFunctions();
+ ReplacePosXFunctions();
+ ReplacePosYFunctions();
+}
+
+bool cTemplatePixmap::CalculateDrawPortSize(cSize &size, map < string, vector< map< string, string > > > *loopTokens) {
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ int pixHeight = parameters->GetNumericParameter(ptHeight);
+ int orientation = parameters->GetNumericParameter(ptOrientation);
+ if (orientation < 0)
+ orientation = orVertical;
+ if (orientation == orHorizontal) {
+ //get function which determinates drawport width
+ cTemplateFunction *scrollFunc = GetScrollFunction();
+ if (!scrollFunc)
+ return false;
+ int drawportWidth = scrollFunc->GetWidth(false) + scrollFunc->GetNumericParameter(ptX) + 10;
+ if (drawportWidth > pixWidth) {
+ size.SetWidth(drawportWidth);
+ size.SetHeight(pixHeight);
+ return true;
+ }
+ } else if (orientation == orVertical) {
+ //check "last" element height
+ InitIterator();
+ cTemplateFunction *f = NULL;
+ int drawportHeight = 1;
+ while (f = GetNextFunction()) {
+ if (f->GetType() == ftLoop) {
+ cTemplateLoopFunction *loopFunc = dynamic_cast<cTemplateLoopFunction*>(f);
+ //get number of loop tokens
+ string loopTokenName = loopFunc->GetParameter(ptName);
+ int numLoopTokens = 0;
+ map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopTokenName);
+ if (hit != loopTokens->end()) {
+ vector< map<string,string> > loopToken = hit->second;
+ numLoopTokens = loopToken.size();
+ //parse first loop token element to get correct height
+ vector< map<string,string> >::iterator firstLoopToken = loopToken.begin();
+ loopFunc->ClearDynamicParameters();
+ loopFunc->ParseDynamicParameters(&(*firstLoopToken));
+ }
+ int orientation = loopFunc->GetNumericParameter(ptOrientation);
+ int yFunc = loopFunc->GetNumericParameter(ptY);
+ int heightFunc = loopFunc->GetLoopElementsHeight();
+ if (loopTokens && orientation == orVertical) {
+ //height is height of loop elements times num loop elements
+ heightFunc = heightFunc * numLoopTokens;
+ } else if (loopTokens && orientation == orHorizontal) {
+ int overflow = loopFunc->GetNumericParameter(ptOverflow);
+ if (overflow == otCut) {
+ //do nothing, height is only height of one line
+ } else if (overflow == otWrap) {
+ int widthFunc = loopFunc->GetLoopElementsWidth();
+ if (widthFunc <= 0)
+ continue;
+ int loopWidth = loopFunc->GetNumericParameter(ptWidth);
+ if (loopWidth <= 0)
+ loopWidth = loopFunc->GetContainerWidth();
+ int elementsPerRow = loopWidth / widthFunc;
+ int rest = loopWidth % widthFunc;
+ if (rest > 0)
+ elementsPerRow++;
+ if (elementsPerRow <= 0)
+ continue;
+ int lines = numLoopTokens / elementsPerRow;
+ rest = numLoopTokens % elementsPerRow;
+ if (rest > 0)
+ lines++;
+ heightFunc = heightFunc * lines;
+ }
+ }
+ int neededHeight = heightFunc + yFunc;
+ if (neededHeight > drawportHeight)
+ drawportHeight = neededHeight;
+ } else {
+ int yFunc = f->GetNumericParameter(ptY);
+ int heightFunc = f->GetHeight();
+ int neededHeight = heightFunc + yFunc;
+ if (neededHeight > drawportHeight)
+ drawportHeight = neededHeight;
+ }
+ }
+ if (drawportHeight > pixHeight) {
+ size.SetWidth(pixWidth);
+ size.SetHeight(drawportHeight);
+ return true;
+ }
+ }
+ size.SetWidth(0);
+ size.SetHeight(0);
+ return false;
+}
+
+void cTemplatePixmap::SetScrollingTextWidth(void) {
+ int orientation = parameters->GetNumericParameter(ptOrientation);
+ if (orientation != orHorizontal)
+ return;
+ int pixWidth = parameters->GetNumericParameter(ptWidth);
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->GetType() == ftDrawText) {
+ int offset = func->GetNumericParameter(ptX);
+ func->SetMaxTextWidth(pixWidth - offset);
+ }
+ }
+}
+
+
+cTemplateFunction *cTemplatePixmap::GetScrollFunction(void) {
+ string scrollElement = parameters->GetParameter(ptScrollElement);
+ if (scrollElement.size() == 0)
+ return NULL;
+ InitIterator();
+ cTemplateFunction *f = NULL;
+ bool foundElement = false;
+ while (f = GetNextFunction()) {
+ string funcName = f->GetParameter(ptName);
+ if (!funcName.compare(scrollElement)) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+cRect cTemplatePixmap::GetPixmapSize(void) {
+ cRect size;
+ size.SetX(GetNumericParameter(ptX));
+ size.SetY(GetNumericParameter(ptY));
+ size.SetWidth(GetNumericParameter(ptWidth));
+ size.SetHeight(GetNumericParameter(ptHeight));
+ return size;
+}
+
+int cTemplatePixmap::GetNumericParameter(eParamType type) {
+ if (!parameters)
+ return -1;
+ return parameters->GetNumericParameter(type);
+}
+
+void cTemplatePixmap::InitIterator(void) {
+ funcIt = functions.begin();
+}
+
+cTemplateFunction *cTemplatePixmap::GetNextFunction(void) {
+ if (funcIt == functions.end())
+ return NULL;
+ cTemplateFunction *func = *funcIt;
+ funcIt++;
+ return func;
+}
+
+bool cTemplatePixmap::Ready(void) {
+ int myX = parameters->GetNumericParameter(ptX);
+ if (myX < 0)
+ return false;
+ int myY = parameters->GetNumericParameter(ptY);
+ if (myY < 0)
+ return false;
+ int myWidth = parameters->GetNumericParameter(ptWidth);
+ if (myWidth < 1)
+ return false;
+ int myHeight = parameters->GetNumericParameter(ptHeight);
+ if (myHeight < 1)
+ return false;
+ return true;
+}
+
+void cTemplatePixmap::ReplaceWidthFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> widths;
+ func->GetNeededWidths(&widths);
+ for (map<eParamType, string>::iterator names = widths.begin(); names !=widths.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcWidth = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcWidth = myFunc->GetWidth();
+ func->SetWidth(type, label, funcWidth);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplaceHeightFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> heights;
+ func->GetNeededHeights(&heights);
+ for (map<eParamType, string>::iterator names = heights.begin(); names !=heights.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcHeight = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcHeight = myFunc->GetHeight();
+ func->SetHeight(type, label, funcHeight);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplacePosXFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> posXs;
+ func->GetNeededPosX(&posXs);
+ for (map<eParamType, string>::iterator names = posXs.begin(); names !=posXs.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcX = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcX = myFunc->GetNumericParameter(ptX);
+ if (funcX > -1) {
+ func->SetX(type, label, funcX);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::ReplacePosYFunctions(void) {
+ InitIterator();
+ cTemplateFunction *func = NULL;
+ while(func = GetNextFunction()) {
+ if (func->ParsedCompletely()) {
+ continue;
+ }
+ multimap<eParamType,string> posYs;
+ func->GetNeededPosY(&posYs);
+ for (map<eParamType, string>::iterator names = posYs.begin(); names !=posYs.end(); names++) {
+ eParamType type = names->first;
+ string label = names->second;
+ int funcY = 0;
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ cTemplateFunction *myFunc = *it;
+ string myFuncName = myFunc->GetParameter(ptName);
+ if (!myFuncName.compare(label)) {
+ funcY = myFunc->GetNumericParameter(ptY);
+ if (funcY > -1) {
+ func->SetY(type, label, funcY);
+ if (func->Updated()) {
+ func->CompleteParameters();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void cTemplatePixmap::Debug(void) {
+ esyslog("skindesigner: pixmap container size x: %d, y: %d, width: %d, height %d", containerX, containerY, containerWidth, containerHeight);
+ parameters->Debug();
+ for (vector<cTemplateFunction*>::iterator it = functions.begin(); it != functions.end(); it++) {
+ (*it)->Debug();
+ }
+}