app_server: Move AlphaMask management into DrawState.
* Give DrawState a real copy constructor, handle deriving in PushState(). (Although clipping region and alpha mask are not cloned, which is on the other hand just what's needed for now.) * Combining alpha masks from previous states is not yet handled. * Remove SetAlphaMask() from DrawingEngine and Painter. It is now done in SetDrawState().
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <Region.h>
|
||||
|
||||
#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 -
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <Point.h>
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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<int32>(&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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <algorithm>
|
||||
#include <stack>
|
||||
|
||||
#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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user