diff options
author | louis <louis.braun@gmx.de> | 2014-09-27 09:25:14 +0200 |
---|---|---|
committer | louis <louis.braun@gmx.de> | 2014-09-27 09:25:14 +0200 |
commit | b0509b5182b6e0d04f05e6b3d5676b0d21f51966 (patch) | |
tree | 22b302342f22843e0815eb5f516c85f1478cbf0b /libcore/pixmapcontainer.c | |
download | vdr-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.c | 477 |
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); +} |