#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); }