From 112d61551e87fc65541e56940ce1546e06c70189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 20 Mar 2008 11:35:51 +0000 Subject: [PATCH] * Add Style::HasTransparency() which just tells if any of the colors that the style uses has an alpha value below 255. * Add support for intermediate rendering passes to IconRenderer. Normally, the whole icon is rendered in a single pass, which means shapes cannot overlap. With the change, intermediate rendering passes are inserted when a shape is encountered that contains transparency. This is an easy way to allow for more feature rich icons, with easy support for glossy/reflective surface effects or other such effects that require support for transparent shapes on top of other shapes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24490 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/libs/icon/IconRenderer.cpp | 43 +++++++++++++++++++++------------- src/libs/icon/IconRenderer.h | 4 ++++ src/libs/icon/style/Style.cpp | 16 +++++++++++++ src/libs/icon/style/Style.h | 2 ++ 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/libs/icon/IconRenderer.cpp b/src/libs/icon/IconRenderer.cpp index 819297e8ab..238b15c8da 100644 --- a/src/libs/icon/IconRenderer.cpp +++ b/src/libs/icon/IconRenderer.cpp @@ -26,7 +26,7 @@ using std::nothrow; -class StyleHandler { +class IconRenderer::StyleHandler { struct StyleItem { Style* style; Transformation transformation; @@ -96,7 +96,7 @@ private: // color const agg::rgba8& -StyleHandler::color(unsigned styleIndex) +IconRenderer::StyleHandler::color(unsigned styleIndex) { StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex); if (!styleItem) { @@ -115,8 +115,8 @@ StyleHandler::color(unsigned styleIndex) // generate_span void -StyleHandler::generate_span(agg::rgba8* span, int x, int y, - unsigned len, unsigned styleIndex) +IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y, + unsigned len, unsigned styleIndex) { StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex); if (!styleItem || !styleItem->style->Gradient()) { @@ -172,12 +172,9 @@ StyleHandler::generate_span(agg::rgba8* span, int x, int y, // _GenerateGradient template void -StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y, unsigned len, - GradientFunction function, - int32 start, int32 end, - const agg::rgba8* gradientColors, - Transformation& gradientTransform) - +IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y, + unsigned len, GradientFunction function, int32 start, int32 end, + const agg::rgba8* gradientColors, Transformation& gradientTransform) { typedef agg::pod_auto_array ColorArray; typedef agg::span_interpolator_linear<> Interpolator; @@ -393,6 +390,12 @@ IconRenderer::_Render(const BRect& r) printf("IconRenderer::_Render() - out of memory\n"); break; } + + // if this is not the first shape, and the style contains + // transparency, commit a render pass of previous shapes + if (i > 0 && style->HasTransparency()) + _CommitRenderPass(styleHandler); + fRasterizer.styles(styleIndex, -1); styleIndex++; @@ -409,12 +412,7 @@ IconRenderer::_Render(const BRect& r) } } - agg::render_scanlines_compound(fRasterizer, - fScanline, - fBinaryScanline, - fBaseRendererPre, - fSpanAllocator, - styleHandler); + _CommitRenderPass(styleHandler, false); if (fGammaTable.gamma() != 1.0) fPixelFormat.apply_gamma_inv(fGammaTable); @@ -423,6 +421,19 @@ IconRenderer::_Render(const BRect& r) //printf("rendering 64x64: %lld\n", system_time() - start); } +// _CommitRenderPass +void +IconRenderer::_CommitRenderPass(StyleHandler& styleHandler, bool reset) +{ + agg::render_scanlines_compound(fRasterizer, + fScanline, + fBinaryScanline, + fBaseRendererPre, + fSpanAllocator, + styleHandler); + if (reset) + fRasterizer.reset(); +} diff --git a/src/libs/icon/IconRenderer.h b/src/libs/icon/IconRenderer.h index d25c1ad412..ac461ecc3d 100644 --- a/src/libs/icon/IconRenderer.h +++ b/src/libs/icon/IconRenderer.h @@ -72,7 +72,11 @@ class IconRenderer { void Demultiply(); private: + class StyleHandler; + void _Render(const BRect& area); + void _CommitRenderPass(StyleHandler& styleHandler, + bool reset = true); BBitmap* fBitmap; const BBitmap* fBackground; diff --git a/src/libs/icon/style/Style.cpp b/src/libs/icon/style/Style.cpp index 7dd456db0e..ce0c4f30af 100644 --- a/src/libs/icon/style/Style.cpp +++ b/src/libs/icon/style/Style.cpp @@ -162,6 +162,22 @@ Style::operator==(const Style& other) const #endif // ICON_O_MATIC +// HasTransparency +bool +Style::HasTransparency() const +{ + if (fGradient) { + int32 count = fGradient->CountColors(); + for (int32 i = 0; i < count; i++) { + color_step* step = fGradient->ColorAtFast(i); + if (step->color.alpha < 255) + return true; + } + return false; + } + return fColor.alpha < 255; +} + // SetColor void Style::SetColor(const rgb_color& color) diff --git a/src/libs/icon/style/Style.h b/src/libs/icon/style/Style.h index 107bfa97eb..e7ee34230c 100644 --- a/src/libs/icon/style/Style.h +++ b/src/libs/icon/style/Style.h @@ -55,6 +55,8 @@ class Style { inline void Notify() {} #endif // ICON_O_MATIC + bool HasTransparency() const; + void SetColor(const rgb_color& color); inline rgb_color Color() const { return fColor; }