* when the client constrained the clipping on a view, the server used to
take an empty region as an indication to remove the clipping, but on R5, this is actually valid... this patch fixes the problem * the ViewState::clipping_region is now consistently used to memorize the user defined clipping of the view state instead of being sometimes used to cache the current view clipping git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16656 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4d664f91ca
commit
8e89843efc
@ -75,6 +75,7 @@ class ViewState {
|
||||
|
||||
::drawing_mode drawing_mode;
|
||||
BRegion clipping_region;
|
||||
bool clipping_region_used;
|
||||
BPoint origin;
|
||||
|
||||
// line modes
|
||||
|
@ -70,7 +70,7 @@ class DrawState {
|
||||
void InverseTransform(BPoint* point) const;
|
||||
|
||||
// additional clipping as requested by client
|
||||
void SetClippingRegion(const BRegion& region);
|
||||
void SetClippingRegion(const BRegion* region);
|
||||
const BRegion* ClippingRegion() const
|
||||
{ return fClippingRegion; }
|
||||
/* inline int32 CountClippingRects() const
|
||||
|
@ -129,8 +129,11 @@ ViewState::ViewState()
|
||||
pen_location.Set(0, 0);
|
||||
pen_size = 1.0;
|
||||
|
||||
// This probably needs to be set to bounds by the owning BView
|
||||
clipping_region.MakeEmpty();
|
||||
// NOTE: the clipping_region is empty
|
||||
// on construction but it is not used yet,
|
||||
// we avoid having to keep track of it via
|
||||
// this flag
|
||||
clipping_region_used = false;
|
||||
|
||||
set_rgb_color(high_color, 0, 0, 0);
|
||||
set_rgb_color(low_color, 255, 255, 255);
|
||||
@ -226,11 +229,15 @@ ViewState::UpdateServerState(BPrivate::PortLink &link)
|
||||
link.Attach<bool>(font_aliasing);
|
||||
|
||||
// we send the 'local' clipping region... if we have one...
|
||||
if (clipping_region_used) {
|
||||
int32 count = clipping_region.CountRects();
|
||||
|
||||
link.Attach<int32>(count);
|
||||
for (int32 i = 0; i < count; i++)
|
||||
link.Attach<BRect>(clipping_region.RectAt(i));
|
||||
} else {
|
||||
// no clipping region
|
||||
link.Attach<int32>(-1);
|
||||
}
|
||||
|
||||
// Although we might have a 'local' clipping region, when we call
|
||||
// BView::GetClippingRegion() we ask for the 'global' one and it
|
||||
@ -299,8 +306,22 @@ ViewState::UpdateFrom(BPrivate::PortLink &link)
|
||||
link.Read<float>(&scale);
|
||||
link.Read<bool>(&font_aliasing);
|
||||
|
||||
// no need to read the clipping region, as it's invalid
|
||||
// next time we need it anyway
|
||||
// read the user clipping
|
||||
// (that's NOT the current View visible clipping but the additional
|
||||
// user specified clipping!)
|
||||
int32 clippingRectCount;
|
||||
link.Read<int32>(&clippingRectCount);
|
||||
if (clippingRectCount >= 0) {
|
||||
clipping_region.MakeEmpty();
|
||||
for (int32 i = 0; i < clippingRectCount; i++) {
|
||||
BRect rect;
|
||||
link.Read<BRect>(&rect);
|
||||
clipping_region.Include(rect);
|
||||
}
|
||||
} else {
|
||||
// no user clipping used
|
||||
clipping_region_used = false;
|
||||
}
|
||||
|
||||
valid_flags = ~B_VIEW_CLIP_REGION_BIT;
|
||||
}
|
||||
@ -2151,10 +2172,10 @@ BView::GetClippingRegion(BRegion* region) const
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
// TODO: For now, the clipping bit is ignored, since the client has no
|
||||
// idea when the clipping in the server changed. -Stephan
|
||||
// NOTE: the client has no idea when the clipping in the server
|
||||
// changed, so it is always read from the serber
|
||||
region->MakeEmpty();
|
||||
|
||||
// if (!fState->IsValid(B_VIEW_CLIP_REGION_BIT) && fOwner && do_owner_check()) {
|
||||
if (fOwner && do_owner_check()) {
|
||||
fOwner->fLink->StartMessage(AS_LAYER_GET_CLIP_REGION);
|
||||
|
||||
@ -2164,21 +2185,15 @@ BView::GetClippingRegion(BRegion* region) const
|
||||
int32 count;
|
||||
fOwner->fLink->Read<int32>(&count);
|
||||
|
||||
fState->clipping_region.MakeEmpty();
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BRect rect;
|
||||
fOwner->fLink->Read<BRect>(&rect);
|
||||
|
||||
fState->clipping_region.Include(rect);
|
||||
region->Include(rect);
|
||||
}
|
||||
fState->valid_flags |= B_VIEW_CLIP_REGION_BIT;
|
||||
}
|
||||
} else {
|
||||
fState->clipping_region.MakeEmpty();
|
||||
}
|
||||
|
||||
*region = fState->clipping_region;
|
||||
}
|
||||
|
||||
|
||||
@ -2186,19 +2201,19 @@ void
|
||||
BView::ConstrainClippingRegion(BRegion* region)
|
||||
{
|
||||
if (do_owner_check()) {
|
||||
int32 count = 0;
|
||||
if (region)
|
||||
count = region->CountRects();
|
||||
|
||||
fOwner->fLink->StartMessage(AS_LAYER_SET_CLIP_REGION);
|
||||
|
||||
// '0' means that in the app_server, there won't be any 'local'
|
||||
// clipping region (it will be = NULL)
|
||||
|
||||
// TODO: note this in the specs
|
||||
if (region) {
|
||||
int32 count = region->CountRects();
|
||||
fOwner->fLink->Attach<int32>(count);
|
||||
for (int32 i = 0; i < count; i++)
|
||||
fOwner->fLink->Attach<BRect>(region->RectAt(i));
|
||||
fOwner->fLink->Attach<clipping_rect>(region->RectAtInt(i));
|
||||
} else {
|
||||
fOwner->fLink->Attach<int32>(-1);
|
||||
// '-1' means that in the app_server, there won't be any 'local'
|
||||
// clipping region (it will be NULL)
|
||||
}
|
||||
|
||||
// we flush here because app_server waits for all the rects
|
||||
fOwner->fLink->Flush();
|
||||
|
@ -214,15 +214,18 @@ DrawState::ReadFromLink(BPrivate::LinkReceiver& link)
|
||||
int32 clipRectCount;
|
||||
link.Read<int32>(&clipRectCount);
|
||||
|
||||
if (clipRectCount >= 0) {
|
||||
BRegion region;
|
||||
if (clipRectCount > 0) {
|
||||
BRect rect;
|
||||
for (int32 i = 0; i < clipRectCount; i++) {
|
||||
link.Read<BRect>(&rect);
|
||||
region.Include(rect);
|
||||
}
|
||||
SetClippingRegion(®ion);
|
||||
} else {
|
||||
// No user clipping used
|
||||
SetClippingRegion(NULL);
|
||||
}
|
||||
SetClippingRegion(region);
|
||||
}
|
||||
|
||||
|
||||
@ -258,12 +261,15 @@ DrawState::WriteToLink(BPrivate::LinkSender& link) const
|
||||
link.Attach<float>(fScale);
|
||||
link.Attach<bool>(fFontAliasing);
|
||||
|
||||
int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0;
|
||||
link.Attach<int32>(clippingRectCount);
|
||||
|
||||
if (fClippingRegion) {
|
||||
int32 clippingRectCount = fClippingRegion->CountRects();
|
||||
link.Attach<int32>(clippingRectCount);
|
||||
for (int i = 0; i < clippingRectCount; i++)
|
||||
link.Attach<BRect>(fClippingRegion->RectAt(i));
|
||||
} else {
|
||||
// no client clipping
|
||||
link.Attach<int32>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,11 +380,11 @@ DrawState::InverseTransform(BPoint* point) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
DrawState::SetClippingRegion(const BRegion& region)
|
||||
DrawState::SetClippingRegion(const BRegion* region)
|
||||
{
|
||||
// reset clipping to that of previous state
|
||||
// (that's the starting point)
|
||||
if (PreviousState() != NULL && PreviousState()->ClippingRegion()) {
|
||||
if (fClippingRegion)
|
||||
*fClippingRegion = *(PreviousState()->ClippingRegion());
|
||||
@ -389,12 +395,15 @@ DrawState::SetClippingRegion(const BRegion& region)
|
||||
fClippingRegion = NULL;
|
||||
}
|
||||
|
||||
// add the clipping from the passed region
|
||||
if (region.Frame().IsValid()) {
|
||||
// intersect with the clipping from the passed region
|
||||
// (even if it is empty)
|
||||
// passing NULL unsets this states additional region,
|
||||
// it will then be the region of the previous state
|
||||
if (region) {
|
||||
if (fClippingRegion)
|
||||
fClippingRegion->IntersectWith(®ion);
|
||||
fClippingRegion->IntersectWith(region);
|
||||
else
|
||||
fClippingRegion = new BRegion(region);
|
||||
fClippingRegion = new BRegion(*region);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1527,7 +1527,7 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
if (PictureToRegion(picture, region, inverse, where) < B_OK)
|
||||
break;
|
||||
|
||||
fCurrentLayer->CurrentState()->SetClippingRegion(region);
|
||||
fCurrentLayer->SetUserClipping(®ion);
|
||||
|
||||
// TODO: reenable AS_LAYER_CLIP_TO_PICTURE
|
||||
#if 0
|
||||
@ -1576,15 +1576,31 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
|
||||
int32 rectCount;
|
||||
link.Read<int32>(&rectCount);
|
||||
|
||||
status_t status = link.Read<int32>(&rectCount);
|
||||
// a negative count means no
|
||||
// region for the current draw state,
|
||||
// but an *empty* region is actually valid!
|
||||
// even if it means no drawing is allowed
|
||||
BRegion region;
|
||||
if (status == B_OK && rectCount >= 0) {
|
||||
for (int32 i = 0; i < rectCount; i++) {
|
||||
BRect r;
|
||||
link.Read<BRect>(&r);
|
||||
clipping_rect r;
|
||||
status = link.Read<clipping_rect>(&r);
|
||||
if (status < B_OK)
|
||||
break;
|
||||
region.Include(r);
|
||||
}
|
||||
fCurrentLayer->SetUserClipping(region);
|
||||
} else
|
||||
status = B_ERROR;
|
||||
|
||||
if (status == B_OK) {
|
||||
fCurrentLayer->SetUserClipping(®ion);
|
||||
} else {
|
||||
// passing NULL sets this states region
|
||||
// to that of the previous state
|
||||
fCurrentLayer->SetUserClipping(NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1749,11 +1765,9 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
||||
BMessage dragMessage;
|
||||
if (link.Read(buffer, bufferSize) == B_OK
|
||||
&& dragMessage.Unflatten(buffer) == B_OK) {
|
||||
// ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
||||
fDesktop->EventDispatcher().SetDragMessage(dragMessage/*, bitmap*/);
|
||||
if (ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken)) {
|
||||
fDesktop->HWInterface()->SetDragBitmap(bitmap, offset);
|
||||
}
|
||||
ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken);
|
||||
fDesktop->EventDispatcher().SetDragMessage(dragMessage,
|
||||
bitmap, offset);
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
@ -1781,7 +1795,9 @@ if (ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken)) {
|
||||
BMessage dragMessage;
|
||||
if (link.Read(buffer, bufferSize) == B_OK
|
||||
&& dragMessage.Unflatten(buffer) == B_OK) {
|
||||
fDesktop->EventDispatcher().SetDragMessage(dragMessage/*, dragRect*/);
|
||||
fDesktop->EventDispatcher().SetDragMessage(dragMessage,
|
||||
NULL, // should be dragRect
|
||||
offset);
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ ViewLayer::Scale() const
|
||||
|
||||
|
||||
void
|
||||
ViewLayer::SetUserClipping(const BRegion& region)
|
||||
ViewLayer::SetUserClipping(const BRegion* region)
|
||||
{
|
||||
fDrawState->SetClippingRegion(region);
|
||||
|
||||
|
@ -64,7 +64,7 @@ class ViewLayer {
|
||||
void SetScale(float scale);
|
||||
float Scale() const;
|
||||
|
||||
void SetUserClipping(const BRegion& region);
|
||||
void SetUserClipping(const BRegion* region);
|
||||
// region is expected in layer coordinates
|
||||
|
||||
// converts the given frame up the view hierarchy and
|
||||
|
Loading…
Reference in New Issue
Block a user