* 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
This commit is contained in:
Stephan Aßmus
2008-03-20 11:35:51 +00:00
parent a886f802fc
commit 112d61551e
4 changed files with 49 additions and 16 deletions
+26 -15
View File
@@ -26,7 +26,7 @@
using std::nothrow; using std::nothrow;
class StyleHandler { class IconRenderer::StyleHandler {
struct StyleItem { struct StyleItem {
Style* style; Style* style;
Transformation transformation; Transformation transformation;
@@ -96,7 +96,7 @@ private:
// color // color
const agg::rgba8& const agg::rgba8&
StyleHandler::color(unsigned styleIndex) IconRenderer::StyleHandler::color(unsigned styleIndex)
{ {
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex); StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex);
if (!styleItem) { if (!styleItem) {
@@ -115,7 +115,7 @@ StyleHandler::color(unsigned styleIndex)
// generate_span // generate_span
void void
StyleHandler::generate_span(agg::rgba8* span, int x, int y, IconRenderer::StyleHandler::generate_span(agg::rgba8* span, int x, int y,
unsigned len, unsigned styleIndex) unsigned len, unsigned styleIndex)
{ {
StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex); StyleItem* styleItem = (StyleItem*)fStyles.ItemAt(styleIndex);
@@ -172,12 +172,9 @@ StyleHandler::generate_span(agg::rgba8* span, int x, int y,
// _GenerateGradient // _GenerateGradient
template<class GradientFunction> template<class GradientFunction>
void void
StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y, unsigned len, IconRenderer::StyleHandler::_GenerateGradient(agg::rgba8* span, int x, int y,
GradientFunction function, unsigned len, GradientFunction function, int32 start, int32 end,
int32 start, int32 end, const agg::rgba8* gradientColors, Transformation& gradientTransform)
const agg::rgba8* gradientColors,
Transformation& gradientTransform)
{ {
typedef agg::pod_auto_array<agg::rgba8, 256> ColorArray; typedef agg::pod_auto_array<agg::rgba8, 256> ColorArray;
typedef agg::span_interpolator_linear<> Interpolator; typedef agg::span_interpolator_linear<> Interpolator;
@@ -393,6 +390,12 @@ IconRenderer::_Render(const BRect& r)
printf("IconRenderer::_Render() - out of memory\n"); printf("IconRenderer::_Render() - out of memory\n");
break; 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); fRasterizer.styles(styleIndex, -1);
styleIndex++; styleIndex++;
@@ -409,12 +412,7 @@ IconRenderer::_Render(const BRect& r)
} }
} }
agg::render_scanlines_compound(fRasterizer, _CommitRenderPass(styleHandler, false);
fScanline,
fBinaryScanline,
fBaseRendererPre,
fSpanAllocator,
styleHandler);
if (fGammaTable.gamma() != 1.0) if (fGammaTable.gamma() != 1.0)
fPixelFormat.apply_gamma_inv(fGammaTable); fPixelFormat.apply_gamma_inv(fGammaTable);
@@ -423,6 +421,19 @@ IconRenderer::_Render(const BRect& r)
//printf("rendering 64x64: %lld\n", system_time() - start); //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();
}
+4
View File
@@ -72,7 +72,11 @@ class IconRenderer {
void Demultiply(); void Demultiply();
private: private:
class StyleHandler;
void _Render(const BRect& area); void _Render(const BRect& area);
void _CommitRenderPass(StyleHandler& styleHandler,
bool reset = true);
BBitmap* fBitmap; BBitmap* fBitmap;
const BBitmap* fBackground; const BBitmap* fBackground;
+16
View File
@@ -162,6 +162,22 @@ Style::operator==(const Style& other) const
#endif // ICON_O_MATIC #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 // SetColor
void void
Style::SetColor(const rgb_color& color) Style::SetColor(const rgb_color& color)
+2
View File
@@ -55,6 +55,8 @@ class Style {
inline void Notify() {} inline void Notify() {}
#endif // ICON_O_MATIC #endif // ICON_O_MATIC
bool HasTransparency() const;
void SetColor(const rgb_color& color); void SetColor(const rgb_color& color);
inline rgb_color Color() const inline rgb_color Color() const
{ return fColor; } { return fColor; }