diff --git a/src/servers/app/AlphaMask.cpp b/src/servers/app/AlphaMask.cpp index 7ad96507b3..80a7fc6445 100644 --- a/src/servers/app/AlphaMask.cpp +++ b/src/servers/app/AlphaMask.cpp @@ -12,6 +12,7 @@ #include "BitmapHWInterface.h" #include "BitmapManager.h" #include "DrawingEngine.h" +#include "DrawState.h" #include "ServerBitmap.h" #include "View.h" @@ -101,7 +102,9 @@ AlphaMask::_RenderPicture(ServerPicture* picture, bool inverse) const // Copy the current state of the client view, so we draw with the right // font, color and everything - engine->SetDrawState(fView->CurrentState()); + DrawState drawState(*fView->CurrentState()); + engine->SetDrawState(&drawState); + OffscreenContext context(engine); if (engine->LockParallelAccess()) { // FIXME ConstrainClippingRegion docs says passing NULL disables diff --git a/src/servers/app/DrawState.cpp b/src/servers/app/DrawState.cpp index da95451036..313c87c4df 100644 --- a/src/servers/app/DrawState.cpp +++ b/src/servers/app/DrawState.cpp @@ -19,6 +19,7 @@ #include +#include "AlphaMask.h" #include "LinkReceiver.h" #include "LinkSender.h" #include "ServerProtocolStructs.h" @@ -28,66 +29,70 @@ using std::nothrow; DrawState::DrawState() - : fOrigin(0.0, 0.0), - fCombinedOrigin(0.0, 0.0), - fScale(1.0), - fCombinedScale(1.0), - fClippingRegion(NULL), + : + fOrigin(0.0, 0.0), + fCombinedOrigin(0.0, 0.0), + fScale(1.0), + fCombinedScale(1.0), + fClippingRegion(NULL), + fAlphaMask(NULL), - fHighColor((rgb_color){ 0, 0, 0, 255 }), - fLowColor((rgb_color){ 255, 255, 255, 255 }), - fPattern(kSolidHigh), + fHighColor((rgb_color){ 0, 0, 0, 255 }), + fLowColor((rgb_color){ 255, 255, 255, 255 }), + fPattern(kSolidHigh), - fDrawingMode(B_OP_COPY), - fAlphaSrcMode(B_PIXEL_ALPHA), - fAlphaFncMode(B_ALPHA_OVERLAY), + fDrawingMode(B_OP_COPY), + fAlphaSrcMode(B_PIXEL_ALPHA), + fAlphaFncMode(B_ALPHA_OVERLAY), - fPenLocation(0.0, 0.0), - fPenSize(1.0), + fPenLocation(0.0, 0.0), + fPenSize(1.0), - fFontAliasing(false), - fSubPixelPrecise(false), - fLineCapMode(B_BUTT_CAP), - fLineJoinMode(B_MITER_JOIN), - fMiterLimit(B_DEFAULT_MITER_LIMIT), - fPreviousState(NULL) + fFontAliasing(false), + fSubPixelPrecise(false), + fLineCapMode(B_BUTT_CAP), + fLineJoinMode(B_MITER_JOIN), + fMiterLimit(B_DEFAULT_MITER_LIMIT), + fPreviousState(NULL) { fUnscaledFontSize = fFont.Size(); } -DrawState::DrawState(DrawState* from) - : fOrigin(0.0, 0.0), - fCombinedOrigin(from->fCombinedOrigin), - fScale(1.0), - fCombinedScale(from->fCombinedScale), - fClippingRegion(NULL), +DrawState::DrawState(const DrawState& other) + : + fOrigin(other.fOrigin), + fCombinedOrigin(other.fCombinedOrigin), + fScale(other.fScale), + fCombinedScale(other.fCombinedScale), + fClippingRegion(NULL), + fAlphaMask(NULL), - fHighColor(from->fHighColor), - fLowColor(from->fLowColor), - fPattern(from->fPattern), + fHighColor(other.fHighColor), + fLowColor(other.fLowColor), + fPattern(other.fPattern), - fDrawingMode(from->fDrawingMode), - fAlphaSrcMode(from->fAlphaSrcMode), - fAlphaFncMode(from->fAlphaFncMode), + fDrawingMode(other.fDrawingMode), + fAlphaSrcMode(other.fAlphaSrcMode), + fAlphaFncMode(other.fAlphaFncMode), - fPenLocation(from->fPenLocation), - fPenSize(from->fPenSize), + fPenLocation(other.fPenLocation), + fPenSize(other.fPenSize), - fFont(from->fFont), - fFontAliasing(from->fFontAliasing), + fFont(other.fFont), + fFontAliasing(other.fFontAliasing), - fSubPixelPrecise(from->fSubPixelPrecise), + fSubPixelPrecise(other.fSubPixelPrecise), - fLineCapMode(from->fLineCapMode), - fLineJoinMode(from->fLineJoinMode), - fMiterLimit(from->fMiterLimit), + fLineCapMode(other.fLineCapMode), + fLineJoinMode(other.fLineJoinMode), + fMiterLimit(other.fMiterLimit), - // Since fScale is reset to 1.0, the unscaled - // font size is the current size of the font - // (which is from->fUnscaledFontSize * from->fCombinedScale) - fUnscaledFontSize(from->fUnscaledFontSize), - fPreviousState(from) + // Since fScale is reset to 1.0, the unscaled + // font size is the current size of the font + // (which is from->fUnscaledFontSize * from->fCombinedScale) + fUnscaledFontSize(other.fUnscaledFontSize), + fPreviousState(NULL) { } @@ -96,13 +101,22 @@ DrawState::~DrawState() { delete fClippingRegion; delete fPreviousState; + delete fAlphaMask; } DrawState* DrawState::PushState() { - DrawState* next = new (nothrow) DrawState(this); + DrawState* next = new (nothrow) DrawState(*this); + + if (next != NULL) { + // Prepare state as derived from this state + next->fOrigin = BPoint(0.0, 0.0); + next->fScale = 1.0; + next->fPreviousState = this; + } + return next; } @@ -373,6 +387,28 @@ DrawState::GetCombinedClippingRegion(BRegion* region) const } +void +DrawState::SetAlphaMask(AlphaMask* mask) +{ + // BeOS compatibility: they implemented ClipToPicture by converting the + // picture to a complex BRegion and used that as a clipping region. As a + // result, youcan't have a picture and a region clipping at the same level + // (but you can either using PushState/PopState, or using + // ConstrainClippingRegion after ClipToPicture...) + // SetClippingRegion(NULL); + + delete fAlphaMask; + fAlphaMask = mask; +} + + +AlphaMask* +DrawState::GetAlphaMask() const +{ + return fAlphaMask; +} + + // #pragma mark - diff --git a/src/servers/app/DrawState.h b/src/servers/app/DrawState.h index c64ebd192a..970cc747e5 100644 --- a/src/servers/app/DrawState.h +++ b/src/servers/app/DrawState.h @@ -20,6 +20,7 @@ #include "ServerFont.h" #include "PatternHandler.h" +class AlphaMask; class BRegion; namespace BPrivate { @@ -31,8 +32,7 @@ namespace BPrivate { class DrawState { public: DrawState(); -private: - DrawState(DrawState* from); + DrawState(const DrawState& other); public: virtual ~DrawState(); @@ -67,6 +67,9 @@ public: bool HasAdditionalClipping() const; bool GetCombinedClippingRegion(BRegion* region) const; + void SetAlphaMask(AlphaMask* mask); + AlphaMask* GetAlphaMask() const; + // coordinate transformations void Transform(float* x, float* y) const; void InverseTransform(float* x, float* y) const; @@ -149,6 +152,8 @@ protected: BRegion* fClippingRegion; + AlphaMask* fAlphaMask; + rgb_color fHighColor; rgb_color fLowColor; Pattern fPattern; diff --git a/src/servers/app/DrawingContext.cpp b/src/servers/app/DrawingContext.cpp index 19c30f654e..28de180324 100644 --- a/src/servers/app/DrawingContext.cpp +++ b/src/servers/app/DrawingContext.cpp @@ -31,7 +31,11 @@ DrawingContext::DrawingContext() fDrawState(new (std::nothrow) DrawState) { } - + + +DrawingContext::~DrawingContext() +{ +} status_t @@ -108,7 +112,7 @@ DrawingContext::SetScale(float scale) float DrawingContext::Scale() const { - return CurrentState()->Scale(); + return fDrawState->Scale(); } @@ -117,11 +121,25 @@ DrawingContext::SetUserClipping(const BRegion* region) { fDrawState->SetClippingRegion(region); - // rebuild clipping (for just this view) + // rebuild clipping (for just this context) RebuildClipping(false); } +void +DrawingContext::SetAlphaMask(AlphaMask* mask) +{ + fDrawState->SetAlphaMask(mask); +} + + +AlphaMask* +DrawingContext::GetAlphaMask() const +{ + return fDrawState->GetAlphaMask(); +} + + //! converts a point from local *drawing* to screen coordinate system void DrawingContext::ConvertToScreenForDrawing(BPoint* point) const diff --git a/src/servers/app/DrawingContext.h b/src/servers/app/DrawingContext.h index 5a4674522a..f791efb50e 100644 --- a/src/servers/app/DrawingContext.h +++ b/src/servers/app/DrawingContext.h @@ -17,6 +17,7 @@ #include +class AlphaMask; class BGradient; class BRegion; class DrawingEngine; @@ -27,8 +28,10 @@ class ServerPicture; class DrawingContext { - public: +public: DrawingContext(); + virtual ~DrawingContext(); + status_t InitCheck() const; virtual void PushState(); @@ -43,7 +46,10 @@ class DrawingContext { void SetUserClipping(const BRegion* region); // region is expected in view coordinates - + + void SetAlphaMask(AlphaMask* mask); + AlphaMask* GetAlphaMask() const; + void ConvertToScreenForDrawing(BPoint* point) const; void ConvertToScreenForDrawing(BRect* rect) const; void ConvertToScreenForDrawing(BRegion* region) const; @@ -70,13 +76,13 @@ class DrawingContext { virtual void ResyncDrawState() {}; virtual void UpdateCurrentDrawingRegion() {}; - protected: +protected: DrawState* fDrawState; }; class OffscreenContext: public DrawingContext { - public: +public: OffscreenContext(DrawingEngine* engine) : fDrawingEngine(engine) {}; @@ -96,7 +102,7 @@ class OffscreenContext: public DrawingContext { void RebuildClipping(bool deep) { /* TODO */ } ServerPicture* GetPicture(int32 token) const { /* TODO */ return NULL; } - private: +private: DrawingEngine* fDrawingEngine; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 1c91ed57c5..03354a805d 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -51,6 +51,7 @@ #include "clipping.h" #include "utf8_functions.h" +#include "AlphaMask.h" #include "AppServer.h" #include "AutoDeleter.h" #include "BBitmapBuffer.h" @@ -1869,7 +1870,8 @@ fDesktop->LockSingleWindow(); link.Read(&pictureToken); if (pictureToken < 0) { - fCurrentView->SetAlphaMask(NULL, false, B_ORIGIN); + fCurrentView->SetAlphaMask(NULL); + _UpdateDrawState(fCurrentView); break; } @@ -1881,7 +1883,10 @@ fDesktop->LockSingleWindow(); if (picture == NULL) break; - fCurrentView->SetAlphaMask(picture, inverse, where); + fCurrentView->SetAlphaMask(new(std::nothrow) AlphaMask( + fCurrentView, picture, inverse, where)); + _UpdateDrawState(fCurrentView); + picture->ReleaseReference(); break; } @@ -2174,7 +2179,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, // that's why you need to use the clipping only for as long // as you have it locked drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion); - drawingEngine->SetAlphaMask(fCurrentView->GetAlphaMask()); switch (code) { case AS_STROKE_LINE: @@ -2840,7 +2844,6 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, break; } - drawingEngine->SetAlphaMask(NULL); drawingEngine->UnlockParallelAccess(); } diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 9c5d68ae4f..7831b45cfb 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -113,7 +113,6 @@ View::View(IntRect frame, IntPoint scrollingOffset, const char* name, fCursor(NULL), fPicture(NULL), - fAlphaMask(NULL), fLocalClipping((BRect)Bounds()), fScreenClipping(), @@ -134,7 +133,6 @@ View::~View() delete fScreenAndUserClipping; delete fUserClipping; delete fDrawState; - delete fAlphaMask; // if (fWindow && this == fWindow->TopView()) // fWindow->SetTopView(NULL); @@ -1575,32 +1573,6 @@ View::InvalidateScreenClipping() } -// TODO we should be storing the ServerPicture here, so we can recompute the -// bitmap mask when the view is scaled, resized or the origin is changed. -// This would allow us to keep a bitmap mask matching exactly the view size. -// Moreover, we should clip that bitmap mask using the region-based clipping, -// so it can mask out all the clipped regions, and we don't have to worry about -// them whendoing further drawing. Essentially, switch from region-based to -// bitmap based clipping for all ourdrawing. -void -View::SetAlphaMask(ServerPicture* picture, bool inverse, BPoint origin) -{ - // BeOS compatibility: they implemented ClipToPicture by converting the - // picture to a complex BRegion and used that as a clipping region. As a - // result, youcan't have a picture and a region clipping at the same level - // (but you can either using PushState/PopState, or using - // ConstrainClippingRegion after ClipToPicture...) - // SetUserClipping(NULL); - - delete fAlphaMask; - if (picture != NULL) { - fAlphaMask = new(std::nothrow) AlphaMask(this, picture, inverse, - origin); - } else - fAlphaMask = NULL; -} - - BRegion& View::_ScreenClipping(BRegion* windowContentClipping, bool force) const { diff --git a/src/servers/app/View.h b/src/servers/app/View.h index 7edd1363d8..c72cd57586 100644 --- a/src/servers/app/View.h +++ b/src/servers/app/View.h @@ -29,7 +29,6 @@ namespace BPrivate { class PortLink; }; -class AlphaMask; class DrawingEngine; class Overlay; class Window; @@ -221,10 +220,6 @@ public: && fScreenAndUserClipping != NULL)); } - void SetAlphaMask(ServerPicture* picture, bool inverse, - BPoint where); - AlphaMask* GetAlphaMask() { return fAlphaMask; } - // debugging void PrintToStream() const; #if 0 @@ -274,7 +269,6 @@ protected: ServerCursor* fCursor; ServerPicture* fPicture; - AlphaMask* fAlphaMask; // clipping BRegion fLocalClipping; diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index f3c1c392c7..6ef0b85c73 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -17,7 +17,6 @@ #include #include -#include "AlphaMask.h" #include "DrawState.h" #include "GlyphLayoutEngine.h" #include "Painter.h" @@ -235,16 +234,6 @@ DrawingEngine::ConstrainClippingRegion(const BRegion* region) } -void -DrawingEngine::SetAlphaMask(AlphaMask* mask) -{ - scanline_unpacked_masked_type* scanline = NULL; - if (mask != NULL) - scanline = mask->Generate(); - fPainter->SetAlphaMask(scanline); -} - - void DrawingEngine::SetDrawState(const DrawState* state, int32 xOffset, int32 yOffset) diff --git a/src/servers/app/drawing/DrawingEngine.h b/src/servers/app/drawing/DrawingEngine.h index 1af932ad46..ce89487ea3 100644 --- a/src/servers/app/drawing/DrawingEngine.h +++ b/src/servers/app/drawing/DrawingEngine.h @@ -25,7 +25,6 @@ class BPoint; class BRect; class BRegion; -class AlphaMask; class DrawState; class Painter; class ServerBitmap; @@ -68,7 +67,6 @@ public: // clipping for all drawing functions, passing a NULL region // will remove any clipping (drawing allowed everywhere) virtual void ConstrainClippingRegion(const BRegion* region); - void SetAlphaMask(AlphaMask* mask); virtual void SetDrawState(const DrawState* state, int32 xOffset = 0, int32 yOffset = 0); diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index f54bd1ea72..8f2765fa32 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -289,6 +289,11 @@ Painter::SetDrawState(const DrawState* data, int32 xOffset, int32 yOffset) fSubpixelPrecise = data->SubPixelPrecise(); + if (data->GetAlphaMask() != NULL) + fMaskedUnpackedScanline = data->GetAlphaMask()->Generate(); + else + fMaskedUnpackedScanline = NULL; + // any of these conditions means we need to use a different drawing // mode instance bool updateDrawingMode @@ -336,13 +341,6 @@ Painter::ConstrainClipping(const BRegion* region) } -void -Painter::SetAlphaMask(scanline_unpacked_masked_type* mask) -{ - fMaskedUnpackedScanline = mask; -} - - // SetHighColor void Painter::SetHighColor(const rgb_color& color) diff --git a/src/servers/app/drawing/Painter/Painter.h b/src/servers/app/drawing/Painter/Painter.h index f5cf15089c..2cd5d6ee3f 100644 --- a/src/servers/app/drawing/Painter/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -54,8 +54,6 @@ public: void ConstrainClipping(const BRegion* region); const BRegion* ClippingRegion() const { return fClippingRegion; } - void SetAlphaMask( - scanline_unpacked_masked_type* mask); void SetDrawState(const DrawState* data, int32 xOffset = 0,