BView: Allow resetting ClipToPicture
Just like for regions, ClipToPicture(NULL) removes any picture clipping at the current state level (clipping in pushed states are not undone).
This commit is contained in:
@@ -5089,24 +5089,23 @@ BView::_SetOwner(BWindow* newOwner)
|
|||||||
void
|
void
|
||||||
BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync)
|
BView::_ClipToPicture(BPicture* picture, BPoint where, bool invert, bool sync)
|
||||||
{
|
{
|
||||||
if (!picture)
|
if (!_CheckOwnerLockAndSwitchCurrent())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_CheckOwnerLockAndSwitchCurrent()) {
|
if (!picture) {
|
||||||
|
fOwner->fLink->StartMessage(AS_VIEW_CLIP_TO_PICTURE);
|
||||||
|
fOwner->fLink->Attach<int32>(-1);
|
||||||
|
} else {
|
||||||
fOwner->fLink->StartMessage(AS_VIEW_CLIP_TO_PICTURE);
|
fOwner->fLink->StartMessage(AS_VIEW_CLIP_TO_PICTURE);
|
||||||
fOwner->fLink->Attach<int32>(picture->Token());
|
fOwner->fLink->Attach<int32>(picture->Token());
|
||||||
fOwner->fLink->Attach<BPoint>(where);
|
fOwner->fLink->Attach<BPoint>(where);
|
||||||
fOwner->fLink->Attach<bool>(invert);
|
fOwner->fLink->Attach<bool>(invert);
|
||||||
|
|
||||||
// TODO: I think that "sync" means another thing here:
|
|
||||||
// the bebook, at least, says so.
|
|
||||||
if (sync)
|
|
||||||
fOwner->fLink->Flush();
|
|
||||||
|
|
||||||
fState->valid_flags &= ~B_VIEW_CLIP_REGION_BIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fState->archiving_flags |= B_VIEW_CLIP_REGION_BIT;
|
// TODO: I think that "sync" means another thing here:
|
||||||
|
// the bebook, at least, says so.
|
||||||
|
if (sync)
|
||||||
|
fOwner->fLink->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@
|
|||||||
#include "AppServer.h"
|
#include "AppServer.h"
|
||||||
#include "AutoDeleter.h"
|
#include "AutoDeleter.h"
|
||||||
#include "BBitmapBuffer.h"
|
#include "BBitmapBuffer.h"
|
||||||
#include "BitmapHWInterface.h"
|
|
||||||
#include "BitmapManager.h"
|
#include "BitmapManager.h"
|
||||||
#include "Desktop.h"
|
#include "Desktop.h"
|
||||||
#include "DirectWindowInfo.h"
|
#include "DirectWindowInfo.h"
|
||||||
@@ -1864,13 +1863,16 @@ fDesktop->LockSingleWindow();
|
|||||||
DTRACE(("ServerWindow %s: Message AS_VIEW_CLIP_TO_PICTURE: "
|
DTRACE(("ServerWindow %s: Message AS_VIEW_CLIP_TO_PICTURE: "
|
||||||
"View: %s\n", Title(), fCurrentView->Name()));
|
"View: %s\n", Title(), fCurrentView->Name()));
|
||||||
|
|
||||||
// TODO: you are not allowed to use View regions here!!!
|
|
||||||
|
|
||||||
int32 pictureToken;
|
int32 pictureToken;
|
||||||
BPoint where;
|
BPoint where;
|
||||||
bool inverse = false;
|
bool inverse = false;
|
||||||
|
|
||||||
link.Read<int32>(&pictureToken);
|
link.Read<int32>(&pictureToken);
|
||||||
|
if (pictureToken < 0) {
|
||||||
|
fCurrentView->SetAlphaMask(NULL, false, B_ORIGIN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
link.Read<BPoint>(&where);
|
link.Read<BPoint>(&where);
|
||||||
if (link.Read<bool>(&inverse) != B_OK)
|
if (link.Read<bool>(&inverse) != B_OK)
|
||||||
break;
|
break;
|
||||||
@@ -1879,12 +1881,7 @@ fDesktop->LockSingleWindow();
|
|||||||
if (picture == NULL)
|
if (picture == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BRegion region;
|
fCurrentView->SetAlphaMask(picture, inverse, where);
|
||||||
// TODO: I think we also need the BView's token
|
|
||||||
// I think PictureToRegion would fit better into the View class (?)
|
|
||||||
if (PictureToRegion(picture, region, inverse, where) == B_OK)
|
|
||||||
fCurrentView->SetUserClipping(®ion);
|
|
||||||
|
|
||||||
picture->ReleaseReference();
|
picture->ReleaseReference();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2177,6 +2174,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
|
|||||||
// that's why you need to use the clipping only for as long
|
// that's why you need to use the clipping only for as long
|
||||||
// as you have it locked
|
// as you have it locked
|
||||||
drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
|
drawingEngine->ConstrainClippingRegion(&fCurrentDrawingRegion);
|
||||||
|
drawingEngine->SetAlphaMask(fCurrentView->GetAlphaMask());
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case AS_STROKE_LINE:
|
case AS_STROKE_LINE:
|
||||||
@@ -2842,6 +2840,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawingEngine->SetAlphaMask(NULL);
|
||||||
drawingEngine->UnlockParallelAccess();
|
drawingEngine->UnlockParallelAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3752,102 +3751,3 @@ ServerWindow::_DirectWindowSetFullScreen(bool enable)
|
|||||||
|
|
||||||
fDesktop->SetWindowFeel(fWindow, feel);
|
fDesktop->SetWindowFeel(fWindow, feel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
ServerWindow::PictureToRegion(ServerPicture* picture, BRegion& region,
|
|
||||||
bool inverse, BPoint where)
|
|
||||||
{
|
|
||||||
// Here the idea is to get rid of the padding bytes in the bitmap,
|
|
||||||
// as padding complicates and slows down the iteration.
|
|
||||||
// TODO: Maybe it's not so nice as it assumes BBitmaps to be aligned
|
|
||||||
// to a 4 byte boundary.
|
|
||||||
BRect bounds(fCurrentView->Bounds());
|
|
||||||
if ((bounds.IntegerWidth() + 1) % 32) {
|
|
||||||
bounds.right = bounds.left + ((bounds.IntegerWidth() + 1) / 32 + 1)
|
|
||||||
* 32 - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
region.MakeEmpty();
|
|
||||||
|
|
||||||
// TODO: Only the alpha channel is relevant, but there is no B_ALPHA8
|
|
||||||
// color space, so we use 75% more memory.
|
|
||||||
UtilityBitmap* bitmap = new UtilityBitmap(bounds, B_RGBA32, 0);
|
|
||||||
if (bitmap == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* TODO stippi says we could use OffscreenWindow to do this, but there
|
|
||||||
* doesn't seem to be a way to create a View without a BView on
|
|
||||||
* application side (the constructor wants a token).
|
|
||||||
* This would be better, as it would avoid the DrawingContext mess.
|
|
||||||
*/
|
|
||||||
OffscreenWindow window(bitmap, "ClipToPicture", fCurrentView->Window());
|
|
||||||
View view(bounds, IntPoint(0, 0), "ClipToPicture");
|
|
||||||
window->SetTopView(view);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Clear the bitmap with the transparent color
|
|
||||||
memset(bitmap->Bits(), 0, bitmap->BitsLength());
|
|
||||||
|
|
||||||
// Render the picture to the bitmap
|
|
||||||
BitmapHWInterface interface(bitmap);
|
|
||||||
DrawingEngine* engine = interface.CreateDrawingEngine();
|
|
||||||
if (engine == NULL) {
|
|
||||||
delete bitmap;
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the current state of the client view, so we draw with the right
|
|
||||||
// font, color and everything
|
|
||||||
engine->SetDrawState(fCurrentView->CurrentState());
|
|
||||||
OffscreenContext context(engine);
|
|
||||||
if (engine->LockParallelAccess())
|
|
||||||
{
|
|
||||||
// FIXME ConstrainClippingRegion docs says passing NULL disables
|
|
||||||
// all clipping. This doesn't work and will crash in Painter.
|
|
||||||
BRegion clipping;
|
|
||||||
clipping.Include(bounds);
|
|
||||||
engine->ConstrainClippingRegion(&clipping);
|
|
||||||
picture->Play(&context);
|
|
||||||
engine->UnlockParallelAccess();
|
|
||||||
}
|
|
||||||
delete engine;
|
|
||||||
|
|
||||||
// TODO stop here: we want agg to clip using the bitmap (with alpha), not
|
|
||||||
// the region.
|
|
||||||
|
|
||||||
int32 width = bounds.IntegerWidth() + 1;
|
|
||||||
int32 height = bounds.IntegerHeight() + 1;
|
|
||||||
if (bitmap != NULL) {
|
|
||||||
uint32 bit = 0;
|
|
||||||
uint32* bits = (uint32*)bitmap->Bits();
|
|
||||||
clipping_rect rect;
|
|
||||||
|
|
||||||
// TODO: A possible optimization would be adding "spans" instead
|
|
||||||
// of 1x1 rects. That would probably help with very complex
|
|
||||||
// BPictures
|
|
||||||
for (int32 y = 0; y < height; y++) {
|
|
||||||
for (int32 x = 0; x < width; x++) {
|
|
||||||
bit = *bits++;
|
|
||||||
if (bit != 0) {
|
|
||||||
rect.left = x;
|
|
||||||
rect.right = rect.left;
|
|
||||||
rect.top = rect.bottom = y;
|
|
||||||
region.Include(rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete bitmap;
|
|
||||||
|
|
||||||
if (inverse) {
|
|
||||||
BRegion inverseRegion;
|
|
||||||
inverseRegion.Include(BRect(fCurrentView->Bounds()));
|
|
||||||
inverseRegion.Exclude(®ion);
|
|
||||||
region = inverseRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -147,11 +147,6 @@ private:
|
|||||||
bool _MessageNeedsAllWindowsLocked(
|
bool _MessageNeedsAllWindowsLocked(
|
||||||
uint32 code) const;
|
uint32 code) const;
|
||||||
|
|
||||||
// TODO: Move me elsewhere
|
|
||||||
status_t PictureToRegion(ServerPicture *picture,
|
|
||||||
BRegion& region, bool inverse,
|
|
||||||
BPoint where);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* fTitle;
|
char* fTitle;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user