From 8b198b4be836b4718cd3ce96e8ba8590697da45a Mon Sep 17 00:00:00 2001 From: mrwastl Date: Mon, 20 Jun 2011 23:13:54 +0200 Subject: opacity support for non-monochrome images --- glcdgraphics/bitmap.c | 19 +++++++++++++------ glcdgraphics/bitmap.h | 2 +- glcdskin/object.c | 4 +++- glcdskin/object.h | 1 + glcdskin/parser.c | 7 +++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/glcdgraphics/bitmap.c b/glcdgraphics/bitmap.c index 40b851f..0ffb039 100644 --- a/glcdgraphics/bitmap.c +++ b/glcdgraphics/bitmap.c @@ -167,11 +167,11 @@ void cBitmap::DrawPixel(int x, int y, uint32_t color) uint32_t bbg = (bg & 0x000000FF); // calculate colour channels of new colour depending on alpha channel and background colour - rfg = (rfg * afg ) / 255 + ( rbg * ( 255 - afg ) ) / 255; - gfg = (gfg * afg ) / 255 + ( gbg * ( 255 - afg ) ) / 255; - bfg = (bfg * afg ) / 255 + ( bbg * ( 255 - afg ) ) / 255; + rfg = (rfg * afg + rbg * (255 - afg)) / 255; + gfg = (gfg * afg + gbg * (255 - afg)) / 255; + bfg = (bfg * afg + bbg * (255 - afg)) / 255; - // as we don't support z-buffering, the new colour will always have alpha level == 0xFF + // as we draw from bottom to top, the new colour will always have alpha level == 0xFF // (it will serve as background colour for future objects that will be drawn onto the current object) col = 0xFF000000 | (rfg << 16) | (gfg << 8) | bfg; } @@ -536,7 +536,7 @@ void cBitmap::DrawSlope(int x1, int y1, int x2, int y2, uint32_t color, int type } } -void cBitmap::DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color, uint32_t bgcolor) +void cBitmap::DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color, uint32_t bgcolor, int opacity) { #ifdef DEBUG printf("%s:%s(%d) '%03d' x '%03d' \n", __FILE__, __FUNCTION__, __LINE__, x, y); @@ -549,6 +549,7 @@ void cBitmap::DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color, u bool ismonochrome = bitmap.IsMonochrome(); int xt, yt; + uint32_t alpha; if (data) { @@ -561,7 +562,13 @@ void cBitmap::DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color, u if (ismonochrome) { DrawPixel(xt+x, yt+y, (cl == cColor::Black) ? color : bgcolor); } else { - DrawPixel(xt+x, yt+y, cl); + if (opacity == 255) { + DrawPixel(xt+x, yt+y, cl); + } else { + alpha = (cl & 0xFF000000) >> 24; + alpha = (alpha * opacity) / 255; + DrawPixel(xt+x, yt+y, (cl & 0x00FFFFFF) | (alpha << 24)); + } } } } diff --git a/glcdgraphics/bitmap.h b/glcdgraphics/bitmap.h index f0e010e..8067cc3 100644 --- a/glcdgraphics/bitmap.h +++ b/glcdgraphics/bitmap.h @@ -119,7 +119,7 @@ public: void DrawRoundRectangle(int x1, int y1, int x2, int y2, uint32_t color, bool filled, int size); void DrawEllipse(int x1, int y1, int x2, int y2, uint32_t color, bool filled, int quadrants); void DrawSlope(int x1, int y1, int x2, int y2, uint32_t color, int type); - void DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color = cColor::White, uint32_t bgcolor = cColor::Black); + void DrawBitmap(int x, int y, const cBitmap & bitmap, uint32_t color = cColor::White, uint32_t bgcolor = cColor::Black, int opacity = 255); int DrawText(int x, int y, int xmax, const std::string & text, const cFont * font, uint32_t color = cColor::White, uint32_t bgcolor = cColor::Black, bool proportional = true, int skipPixels = 0); int DrawCharacter(int x, int y, int xmax, uint32_t c, const cFont * font, diff --git a/glcdskin/object.c b/glcdskin/object.c index 336f21e..107e8f5 100644 --- a/glcdskin/object.c +++ b/glcdskin/object.c @@ -55,6 +55,7 @@ cSkinObject::cSkinObject(cSkinDisplay * Parent) mChangeDelay(-1), // delay between two images frames: -1: not animated / don't care mStoredImagePath(""), mImageFrameId(0), // start with 1st frame + mOpacity(255), // default: full opacity mScrollLoopMode(-1), // scroll (text) or loop (image) mode: default (-1) mScrollLoopReached(false), // if scroll/loop == once: already looped once? mScrollSpeed(0), // scroll speed: default (0) @@ -97,6 +98,7 @@ cSkinObject::cSkinObject(const cSkinObject & Src) mChangeDelay(-1), mStoredImagePath(Src.mStoredImagePath), mImageFrameId(0), + mOpacity(Src.mOpacity), mScrollLoopMode(Src.mScrollLoopMode), mScrollLoopReached(Src.mScrollLoopReached), mScrollSpeed(Src.mScrollSpeed), @@ -384,7 +386,7 @@ void cSkinObject::Render(GLCD::cBitmap * screen) if (mColor == cColor::ERRCOL) screen->DrawBitmap(Pos().x, Pos().y, *bitmap); else - screen->DrawBitmap(Pos().x, Pos().y, *bitmap, mColor, mBackgroundColor); + screen->DrawBitmap(Pos().x, Pos().y, *bitmap, mColor, mBackgroundColor, mOpacity); } if (mScrollLoopMode != -1) // if == -1: currScrollLoopMode already contains correct value diff --git a/glcdskin/object.h b/glcdskin/object.h index 5131cd4..e48b46f 100644 --- a/glcdskin/object.h +++ b/glcdskin/object.h @@ -148,6 +148,7 @@ private: std::string mStoredImagePath; // stored image path int mImageFrameId; // frame ID of image + int mOpacity; // opacity of an image ([0, 255], default 255) int mScrollLoopMode; // scroll (text) or loop (image) mode: -1: default, 0: never, 1: once, 2: always bool mScrollLoopReached; // if scroll/loop == once: already looped once? diff --git a/glcdskin/parser.c b/glcdskin/parser.c index b017326..71df8e1 100644 --- a/glcdskin/parser.c +++ b/glcdskin/parser.c @@ -281,6 +281,7 @@ bool StartElem(const std::string & name, std::map & att ATTRIB_OPT_FUNC_PARAM("bgcolor", object->ParseColor, object->mBackgroundColor); ATTRIB_MAN_FUNC("path", object->mPath.Parse); ATTRIB_OPT_FUNC("loop", object->ParseScrollLoopMode); + ATTRIB_OPT_FUNC_PARAM("opacity", object->ParseIntParam, object->mOpacity); } else if (name == "text" || name == "scrolltext") @@ -341,6 +342,12 @@ bool StartElem(const std::string & name, std::map & att --object->mPos2.y; } #endif + // range checks + if (object->mOpacity < 0) + object->mOpacity = 0; + else if (object->mOpacity > 255) + object->mOpacity = 255; + } else TAG_ERR_REMAIN(context[context.size() - 1].c_str()); -- cgit v1.2.3