diff --git a/src/servers/app/drawing/AlphaMask.cpp b/src/servers/app/drawing/AlphaMask.cpp index 2b744cd548..391c929466 100644 --- a/src/servers/app/drawing/AlphaMask.cpp +++ b/src/servers/app/drawing/AlphaMask.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2014, Haiku, Inc. + * Copyright 2014-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Adrien Destugues * Stephan Aßmus + * Julian Harnath */ @@ -26,6 +27,7 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin, fPicture(picture), fInverse(inverse), fOrigin(origin), + fBackgroundOpacity(0), fDrawState(drawState), fViewBounds(), @@ -43,9 +45,34 @@ AlphaMask::AlphaMask(ServerPicture* picture, bool inverse, BPoint origin, } +AlphaMask::AlphaMask(uint8 backgroundOpacity) + : + fPreviousMask(NULL), + + fPicture(NULL), + fInverse(false), + fOrigin(0, 0), + fBackgroundOpacity(backgroundOpacity), + fDrawState(), + + fViewBounds(), + fViewOffset(), + + fCachedBitmap(NULL), + fCachedBounds(), + fCachedOffset(), + + fBuffer(), + fCachedMask(), + fScanline(fCachedMask) +{ +} + + AlphaMask::~AlphaMask() { - fPicture->ReleaseReference(); + if (fPicture != NULL) + fPicture->ReleaseReference(); delete[] fCachedBitmap; SetPrevious(NULL); } @@ -81,7 +108,13 @@ AlphaMask::SetPrevious(AlphaMask* mask) scanline_unpacked_masked_type* AlphaMask::Generate() { - if (fPicture == NULL || !fViewBounds.IsValid()) + if (fPicture == NULL) { + fBuffer.attach(NULL, 0, 0, 0); + _AttachMaskToBuffer(); + return &fScanline; + } + + if (!fViewBounds.IsValid()) return NULL; // See if a cached bitmap can be used. Don't use it when the view offset @@ -162,9 +195,7 @@ AlphaMask::Generate() fCachedOffset = fViewOffset; fBuffer.attach(fCachedBitmap, width, height, width); - - fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x, - fViewOffset.y + fOrigin.y, fInverse ? 255 : 0); + _AttachMaskToBuffer(); return &fScanline; } @@ -184,7 +215,7 @@ AlphaMask::_RenderPicture() const } // Clear the bitmap with the transparent color - memset(bitmap->Bits(), 0, bitmap->BitsLength()); + memset(bitmap->Bits(), fBackgroundOpacity, bitmap->BitsLength()); // Render the picture to the bitmap BitmapHWInterface interface(bitmap); @@ -213,3 +244,13 @@ AlphaMask::_RenderPicture() const return bitmap; } + +void +AlphaMask::_AttachMaskToBuffer() +{ + uint8 outsideOpacity = fInverse ? 255 - fBackgroundOpacity + : fBackgroundOpacity; + + fCachedMask.attach(fBuffer, fViewOffset.x + fOrigin.x, + fViewOffset.y + fOrigin.y, outsideOpacity); +} diff --git a/src/servers/app/drawing/AlphaMask.h b/src/servers/app/drawing/AlphaMask.h index 661ec7768e..83ceb7fd2f 100644 --- a/src/servers/app/drawing/AlphaMask.h +++ b/src/servers/app/drawing/AlphaMask.h @@ -1,5 +1,5 @@ /* - * Copyright 2014, Haiku, Inc. + * Copyright 2014-2015, Haiku, Inc. * Distributed under the terms of the MIT License. */ @@ -23,6 +23,7 @@ class AlphaMask : public BReferenceable { public: AlphaMask(ServerPicture* mask, bool inverse, BPoint origin, const DrawState& drawState); + AlphaMask(uint8 backgroundOpacity); ~AlphaMask(); void Update(BRect bounds, BPoint offset); @@ -33,6 +34,7 @@ public: private: ServerBitmap* _RenderPicture() const; + void _AttachMaskToBuffer(); private: @@ -41,10 +43,18 @@ private: ServerPicture* fPicture; const bool fInverse; BPoint fOrigin; + // position of this mask, relative to + // either its parent mask, or (if there + // is none) the canvas + uint8 fBackgroundOpacity; DrawState fDrawState; + // draw state used for drawing fPicture BRect fViewBounds; + // determines alpha mask size BPoint fViewOffset; + // position of alpha mask in screen + // coordinates uint8* fCachedBitmap; BRect fCachedBounds;