summaryrefslogtreecommitdiff
path: root/libcore/pixmapcontainer.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 /libcore/pixmapcontainer.c
downloadvdr-plugin-skindesigner-0.0.1.tar.gz
vdr-plugin-skindesigner-0.0.1.tar.bz2
initial commit version 0.0.10.0.1
Diffstat (limited to 'libcore/pixmapcontainer.c')
-rw-r--r--libcore/pixmapcontainer.c477
1 files changed, 477 insertions, 0 deletions
diff --git a/libcore/pixmapcontainer.c b/libcore/pixmapcontainer.c
new file mode 100644
index 0000000..6329638
--- /dev/null
+++ b/libcore/pixmapcontainer.c
@@ -0,0 +1,477 @@
+#define __STL_CONFIG_H
+#include "pixmapcontainer.h"
+#include "../config.h"
+
+cMutex cPixmapContainer::mutex;
+cOsd *cPixmapContainer::osd = NULL;
+eFlushState cPixmapContainer::flushState = fsOpen;
+
+cPixmapContainer::cPixmapContainer(int numPixmaps) {
+ this->numPixmaps = numPixmaps;
+ pixContainerInit = true;
+ mutex.Lock();
+ pixmaps = new cPixmap*[numPixmaps];
+ pixmapsTransparency = new int[numPixmaps];
+ for(int i=0; i < numPixmaps; i++) {
+ pixmaps[i] = NULL;
+ pixmapsTransparency[i] = 0;
+ }
+ mutex.Unlock();
+ checkRunning = false;
+ fadeTime = 0;
+ deleteOsdOnExit = false;
+}
+
+cPixmapContainer::~cPixmapContainer(void) {
+ for (int i=0; i < numPixmaps; i++) {
+ mutex.Lock();
+ if (pixmaps[i] && osd) {
+ osd->DestroyPixmap(pixmaps[i]);
+ pixmaps[i] = NULL;
+ }
+ mutex.Unlock();
+ }
+ delete[] pixmaps;
+ delete[] pixmapsTransparency;
+ if (deleteOsdOnExit && osd) {
+ mutex.Lock();
+ delete osd;
+ osd = NULL;
+ mutex.Unlock();
+ }
+}
+
+bool cPixmapContainer::CreateOsd(int Left, int Top, int Width, int Height) {
+ if (osd) {
+ return true;
+ }
+ cOsd *newOsd = cOsdProvider::NewOsd(Left, Top);
+ if (newOsd) {
+ tArea Area = { 0, 0, Width, Height, 32 };
+ if (newOsd->SetAreas(&Area, 1) == oeOk) {
+ osd = newOsd;
+ return true;
+ }
+ }
+ return false;
+}
+
+void cPixmapContainer::LockFlush(void) {
+ flushState = fsLock;
+}
+
+void cPixmapContainer::OpenFlush(void) {
+ flushState = fsOpen;
+}
+
+bool cPixmapContainer::PixmapExists(int num) {
+ cMutexLock MutexLock(&mutex);
+ if (pixmaps[num])
+ return true;
+ return false;
+}
+
+void cPixmapContainer::DoFlush(void) {
+ cMutexLock MutexLock(&mutex);
+ if (!osd || (checkRunning && !Running()))
+ return;
+ if (flushState == fsOpen) {
+ osd->Flush();
+ }
+}
+
+void cPixmapContainer::CreatePixmap(int num, int Layer, const cRect &ViewPort, const cRect &DrawPort) {
+ cMutexLock MutexLock(&mutex);
+ if (!osd || (checkRunning && !Running()))
+ return;
+ pixmaps[num] = osd->CreatePixmap(Layer, ViewPort, DrawPort);
+ pixmaps[num]->Fill(clrTransparent);
+ if (pixContainerInit && fadeTime) {
+ pixmaps[num]->SetAlpha(0);
+ } else if (pixmapsTransparency[num] > 0) {
+ int alpha = (100 - pixmapsTransparency[num])*255/100;
+ pixmaps[num]->SetAlpha(alpha);
+ }
+}
+
+bool cPixmapContainer::DestroyPixmap(int num) {
+ cMutexLock MutexLock(&mutex);
+ if (pixmaps[num] && osd) {
+ osd->DestroyPixmap(pixmaps[num]);
+ pixmaps[num] = NULL;
+ return true;
+ }
+ return false;
+}
+
+void cPixmapContainer::DrawText(int num, const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, std::string fontName, int fontSize) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ fontManager->Lock();
+ cFont *font = fontManager->Font(fontName, fontSize);
+ if (font)
+ pixmaps[num]->DrawText(Point, s, ColorFg, ColorBg, font);
+ fontManager->Unlock();
+}
+
+
+void cPixmapContainer::DrawRectangle(int num, const cRect &Rect, tColor Color) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->DrawRectangle(Rect, Color);
+}
+
+void cPixmapContainer::DrawEllipse(int num, const cRect &Rect, tColor Color, int Quadrants) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->DrawEllipse(Rect, Color, Quadrants);
+}
+
+void cPixmapContainer::DrawImage(int num, const cPoint &Point, const cImage &Image) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->DrawImage(Point, Image);
+}
+
+void cPixmapContainer::DrawBitmap(int num, const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->DrawBitmap(Point, Bitmap, ColorFg, ColorBg, Overlay);
+}
+
+void cPixmapContainer::Fill(int num, tColor Color) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->Fill(Color);
+}
+
+void cPixmapContainer::SetAlpha(int num, int Alpha) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->SetAlpha(Alpha);
+}
+
+void cPixmapContainer::SetTransparency(int num, int Transparency) {
+ if (Transparency < 0 && Transparency > 100)
+ return;
+ pixmapsTransparency[num] = Transparency;
+}
+
+void cPixmapContainer::SetLayer(int num, int Layer) {
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->SetLayer(Layer);
+}
+
+int cPixmapContainer::Width(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int width = pixmaps[num]->ViewPort().Width();
+ return width;
+}
+
+int cPixmapContainer::Height(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int height = pixmaps[num]->ViewPort().Height();
+ return height;
+}
+
+int cPixmapContainer::DrawportWidth(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int width = pixmaps[num]->DrawPort().Width();
+ return width;
+}
+
+int cPixmapContainer::DrawportHeight(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int height = pixmaps[num]->DrawPort().Height();
+ return height;
+}
+
+int cPixmapContainer::DrawportX(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int x = pixmaps[num]->DrawPort().X();
+ return x;
+}
+
+int cPixmapContainer::DrawportY(int num) {
+ if (checkRunning && !Running())
+ return 0;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return 0;
+ int y = pixmaps[num]->DrawPort().Y();
+ return y;
+}
+
+void cPixmapContainer::SetDrawPortPoint(int num, const cPoint &Point) {
+ if (checkRunning && !Running())
+ return;
+ cMutexLock MutexLock(&mutex);
+ if (!pixmaps[num])
+ return;
+ pixmaps[num]->SetDrawPortPoint(Point);
+}
+
+/***************************************************************************
+* HELPERS -- do not access the pixmaps array directly, use wrapper functions
+* to ensure that a proper lock is set before accessing pixmaps
+****************************************************************************/
+
+void cPixmapContainer::FadeIn(void) {
+ if (!fadeTime)
+ return;
+ uint64_t Start = cTimeMs::Now();
+ int FadeFrameTime = fadeTime / 10;
+ while (Running()) {
+ uint64_t Now = cTimeMs::Now();
+ double t = min(double(Now - Start) / fadeTime, 1.0);
+ int Alpha = t * ALPHA_OPAQUE;
+ for (int i = 0; i < numPixmaps; i++) {
+ if (!PixmapExists(i))
+ continue;
+ if (pixmapsTransparency[i] > 0) {
+ int alpha = (100 - pixmapsTransparency[i])*Alpha/100;
+ SetAlpha(i, alpha);
+ } else {
+ SetAlpha(i, Alpha);
+ }
+ }
+ DoFlush();
+ int Delta = cTimeMs::Now() - Now;
+ if (Running() && (Delta < FadeFrameTime))
+ cCondWait::SleepMs(FadeFrameTime - Delta);
+ if ((int)(Now - Start) > fadeTime)
+ break;
+ }
+}
+
+void cPixmapContainer::FadeOut(void) {
+ if (!fadeTime)
+ return;
+ uint64_t Start = cTimeMs::Now();
+ int FadeFrameTime = fadeTime / 10;
+ while (true) {
+ uint64_t Now = cTimeMs::Now();
+ double t = min(double(Now - Start) / fadeTime, 1.0);
+ int Alpha = (1 - t) * ALPHA_OPAQUE;
+ for (int i = 0; i < numPixmaps; i++) {
+ if (!PixmapExists(i))
+ continue;
+ if (pixmapsTransparency[i] > 0) {
+ int alpha = (100 - pixmapsTransparency[i])*Alpha/100;
+ SetAlpha(i, alpha);
+ } else {
+ SetAlpha(i, Alpha);
+ }
+ }
+ DoFlush();
+ int Delta = cTimeMs::Now() - Now;
+ if (Running() && (Delta < FadeFrameTime))
+ cCondWait::SleepMs(FadeFrameTime - Delta);
+ if ((int)(Now - Start) > fadeTime)
+ break;
+ }
+}
+
+/*****************************************
+* scrollSpeed: 1 slow
+* 2 medium
+* 3 fast
+******************************************/
+void cPixmapContainer::ScrollHorizontal(int num, int scrollDelay, int scrollSpeed, int scrollMode) {
+ bool carriageReturn = (scrollMode == 1) ? true : false;
+
+ int scrollDelta = 1;
+ int drawPortX;
+
+ int FrameTime = 0;
+ if (scrollSpeed == 1)
+ FrameTime = 50;
+ else if (scrollSpeed == 2)
+ FrameTime = 30;
+ else
+ FrameTime = 15;
+ if (!Running())
+ return;
+ int maxX = DrawportWidth(num) - Width(num);
+ bool doSleep = false;
+ while (Running()) {
+ if (doSleep) {
+ DoSleep(scrollDelay);
+ doSleep = false;
+ }
+ if (!Running())
+ return;
+ uint64_t Now = cTimeMs::Now();
+ drawPortX = DrawportX(num);
+ drawPortX -= scrollDelta;
+
+ if (abs(drawPortX) > maxX) {
+ DoSleep(scrollDelay);
+ if (carriageReturn)
+ drawPortX = 0;
+ else {
+ scrollDelta *= -1;
+ drawPortX -= scrollDelta;
+ }
+ doSleep = true;
+ }
+ if (!carriageReturn && (drawPortX == 0)) {
+ scrollDelta *= -1;
+ doSleep = true;
+ }
+ SetDrawPortPoint(num, cPoint(drawPortX, 0));
+ int Delta = cTimeMs::Now() - Now;
+ DoFlush();
+ if (Running() && (Delta < FrameTime))
+ cCondWait::SleepMs(FrameTime - Delta);
+ }
+}
+
+/*****************************************
+* scrollSpeed: 1 slow
+* 2 medium
+* 3 fast
+******************************************/
+void cPixmapContainer::ScrollVertical(int num, int scrollDelay, int scrollSpeed) {
+ if (!scrollSpeed)
+ return;
+ DoSleep(scrollDelay);
+ int drawPortY;
+ int FrameTime = 0;
+ if (scrollSpeed == 1)
+ FrameTime = 50;
+ else if (scrollSpeed == 2)
+ FrameTime = 30;
+ else
+ FrameTime = 15;
+ int maxY = DrawportHeight(num) - Height(num);
+ bool doSleep = false;
+ while (Running()) {
+ if (doSleep) {
+ doSleep = false;
+ DoSleep(scrollDelay);
+ }
+ uint64_t Now = cTimeMs::Now();
+ drawPortY = DrawportY(num);
+ drawPortY -= 1;
+ if (abs(drawPortY) > maxY) {
+ doSleep = true;
+ DoSleep(scrollDelay);
+ drawPortY = 0;
+ }
+ SetDrawPortPoint(num, cPoint(0, drawPortY));
+ if (doSleep) {
+ DoSleep(scrollDelay);
+ }
+ int Delta = cTimeMs::Now() - Now;
+ DoFlush();
+ if (Running() && (Delta < FrameTime))
+ cCondWait::SleepMs(FrameTime - Delta);
+ }
+}
+
+void cPixmapContainer::CancelSave(void) {
+ Cancel(-1);
+ while (Active())
+ cCondWait::SleepMs(10);
+}
+
+void cPixmapContainer::DoSleep(int duration) {
+ int sleepSlice = 10;
+ for (int i = 0; Running() && (i*sleepSlice < duration); i++)
+ cCondWait::SleepMs(sleepSlice);
+}
+
+void cPixmapContainer::DrawBlendedBackground(int num, int xStart, int width, tColor color, tColor colorBlending, bool fromTop) {
+ int height = Height(num);
+ int numSteps = 16;
+ int alphaStep = 0x0F;
+ int alpha = 0x00;
+ int step, begin, end;
+ if (fromTop) {
+ step = 1;
+ begin = 0;
+ end = numSteps;
+ } else {
+ step = -1;
+ begin = height;
+ end = height - numSteps;
+ }
+ tColor clr;
+ bool cont = true;
+ for (int i = begin; cont; i = i + step) {
+ clr = AlphaBlend(color, colorBlending, alpha);
+ DrawRectangle(num, cRect(xStart,i,width,1), clr);
+ alpha += alphaStep;
+ if (i == end)
+ cont = false;
+ }
+}
+
+void cPixmapContainer::DrawRoundedCorners(int num, int radius, int x, int y, int width, int height) {
+ if (radius > 2) {
+ DrawEllipse(num, cRect(x, y, radius, radius), clrTransparent, -2);
+ DrawEllipse(num, cRect(x + width - radius, y , radius, radius), clrTransparent, -1);
+ DrawEllipse(num, cRect(x, y + height - radius, radius, radius), clrTransparent, -3);
+ DrawEllipse(num, cRect(x + width - radius, y + height - radius, radius, radius), clrTransparent, -4);
+ }
+}
+
+void cPixmapContainer::DrawRoundedCornersWithBorder(int num, tColor borderColor, int radius, int width, int height) {
+ if (radius < 3)
+ return;
+ DrawEllipse(num, cRect(0,0,radius,radius), borderColor, -2);
+ DrawEllipse(num, cRect(-1,-1,radius,radius), clrTransparent, -2);
+
+ DrawEllipse(num, cRect(width-radius,0,radius,radius), borderColor, -1);
+ DrawEllipse(num, cRect(width-radius+1,-1,radius,radius), clrTransparent, -1);
+
+ DrawEllipse(num, cRect(0,height-radius,radius,radius), borderColor, -3);
+ DrawEllipse(num, cRect(-1,height-radius+1,radius,radius), clrTransparent, -3);
+
+ DrawEllipse(num, cRect(width-radius,height-radius,radius,radius), borderColor, -4);
+ DrawEllipse(num, cRect(width-radius+1,height-radius+1,radius,radius), clrTransparent, -4);
+}