/* * Copyright 2014-2015, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef ALPHA_MASK_H #define ALPHA_MASK_H #include #include #include "agg_clipped_alpha_mask.h" #include "ServerPicture.h" #include "DrawState.h" #include "drawing/Painter/defines.h" #include "IntRect.h" class BShape; class ServerBitmap; class ServerPicture; class shape_data; class UtilityBitmap; // #pragma mark - AlphaMask class AlphaMask : public BReferenceable { public: AlphaMask(AlphaMask* previousMask, bool inverse); AlphaMask(AlphaMask* previousMask, AlphaMask* other); AlphaMask(uint8 backgroundOpacity); virtual ~AlphaMask(); IntPoint SetCanvasGeometry(IntPoint origin, IntRect bounds); scanline_unpacked_masked_type* Scanline() { return &fScanline; } agg::clipped_alpha_mask* Mask() { return &fMask; } size_t BitmapSize() const; bool IsInverted() const { return fInverse; } bool IsClipped() const { return fClippedToCanvas; } uint8 OutsideOpacity() const { return fOutsideOpacity; } protected: ServerBitmap* _CreateTemporaryBitmap(BRect bounds) const; void _Generate(); void _SetNoClipping(); const IntRect& _PreviousMaskBounds() const; virtual void _AddToCache() = 0; void _SetOutsideOpacity(); private: virtual ServerBitmap* _RenderSource(const IntRect& canvasBounds) = 0; virtual IntPoint _Offset() = 0; void _AttachMaskToBuffer(); protected: BReference fPreviousMask; IntRect fBounds; bool fClippedToCanvas; recursive_lock fLock; private: friend class AlphaMaskCache; IntPoint fCanvasOrigin; IntRect fCanvasBounds; const bool fInverse; uint8 fBackgroundOpacity; uint8 fOutsideOpacity; int32 fNextMaskCount; bool fInCache; uint32 fIndirectCacheReferences; // number of times this mask has been // seen as "previous mask" of another // one in the cache, without being // in the cache itself BReference fBits; agg::rendering_buffer fBuffer; agg::clipped_alpha_mask fMask; scanline_unpacked_masked_type fScanline; }; class UniformAlphaMask : public AlphaMask { public: UniformAlphaMask(uint8 opacity); private: virtual ServerBitmap* _RenderSource(const IntRect& canvasBounds); virtual IntPoint _Offset(); virtual void _AddToCache(); }; // #pragma mark - VectorAlphaMask template class VectorAlphaMask : public AlphaMask { public: VectorAlphaMask(AlphaMask* previousMask, BPoint where, bool inverse); VectorAlphaMask(AlphaMask* previousMask, VectorAlphaMask* other); private: virtual ServerBitmap* _RenderSource(const IntRect& canvasBounds); virtual IntPoint _Offset(); protected: BPoint fWhere; }; // #pragma mark - PictureAlphaMask class PictureAlphaMask : public VectorAlphaMask { public: PictureAlphaMask(AlphaMask* previousMask, ServerPicture* picture, const DrawState& drawState, BPoint where, bool inverse); virtual ~PictureAlphaMask(); void DrawVectors(Canvas* canvas); BRect DetermineBoundingBox() const; const DrawState& GetDrawState() const; private: virtual void _AddToCache(); private: BReference fPicture; ObjectDeleter fDrawState; }; // #pragma mark - ShapeAlphaMask class ShapeAlphaMask : public VectorAlphaMask { private: ShapeAlphaMask(AlphaMask* previousMask, const shape_data& shape, BPoint where, bool inverse); ShapeAlphaMask(AlphaMask* previousMask, ShapeAlphaMask* other); public: virtual ~ShapeAlphaMask(); static ShapeAlphaMask* Create(AlphaMask* previousMask, const shape_data& shape, BPoint where, bool inverse); void DrawVectors(Canvas* canvas); BRect DetermineBoundingBox() const; const DrawState& GetDrawState() const; private: virtual void _AddToCache(); private: friend class AlphaMaskCache; BReference fShape; BRect fShapeBounds; static DrawState* fDrawState; }; #endif // ALPHA_MASK_H