* introduced IntPoint and IntRect, which are just like BPoint and BRect,

but use integer coordinates. These are now used in ViewLayer for the
  coordinate system (layout, scrolling offset, view bitmap layout)
* modest performance improvements by inlining some very often used
  methods, and by preventing to go down the entire layer tree too often,
  for example InvalidateScreenClipping was always called in the deep
  mode, therefor it is save to assume that the tree does not have to
  be traversed as soon as the clipping is already invalid


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19390 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2006-11-29 03:20:07 +00:00
parent ba688f3640
commit 264fe59ded
8 changed files with 871 additions and 128 deletions

View File

@ -0,0 +1,79 @@
/*
* Copyright 2001-2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Frans van Nispen
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "IntPoint.h"
#include <stdio.h>
#include "IntRect.h"
void
IntPoint::ConstrainTo(const IntRect& r)
{
x = max_c(min_c(x, r.right), r.left);
y = max_c(min_c(y, r.bottom), r.top);
}
void
IntPoint::PrintToStream() const
{
printf("IntPoint(x:%ld, y:%ld)\n", x, y);
}
IntPoint
IntPoint::operator+(const IntPoint& p) const
{
return IntPoint(x + p.x, y + p.y);
}
IntPoint
IntPoint::operator-(const IntPoint& p) const
{
return IntPoint(x - p.x, y - p.y);
}
IntPoint &
IntPoint::operator+=(const IntPoint& p)
{
x += p.x;
y += p.y;
return *this;
}
IntPoint &
IntPoint::operator-=(const IntPoint& p)
{
x -= p.x;
y -= p.y;
return *this;
}
bool
IntPoint::operator!=(const IntPoint& p) const
{
return x != p.x || y != p.y;
}
bool
IntPoint::operator==(const IntPoint& p) const
{
return x == p.x && y == p.y;
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2001-2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Frans van Nispen
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef INT_POINT_H
#define INT_POINT_H
#include <Point.h>
class IntRect;
class IntPoint {
public:
int32 x;
int32 y;
IntPoint();
IntPoint(int32 X, int32 Y);
IntPoint(const IntPoint& p);
IntPoint(const BPoint& p);
IntPoint& operator=(const IntPoint& p);
void Set(int32 x, int32 y);
void ConstrainTo(const IntRect& r);
void PrintToStream() const;
IntPoint operator+(const IntPoint& p) const;
IntPoint operator-(const IntPoint& p) const;
IntPoint& operator+=(const IntPoint& p);
IntPoint& operator-=(const IntPoint& p);
bool operator!=(const IntPoint& p) const;
bool operator==(const IntPoint& p) const;
// conversion to BPoint
operator BPoint() const
{ return BPoint((float)x, (float)y); }
};
inline
IntPoint::IntPoint()
: x(0),
y(0)
{
}
inline
IntPoint::IntPoint(int32 x, int32 y)
: x(x),
y(y)
{
}
inline
IntPoint::IntPoint(const IntPoint& p)
: x(p.x),
y(p.y)
{
}
inline
IntPoint::IntPoint(const BPoint& p)
: x((int32)p.x),
y((int32)p.y)
{
}
inline IntPoint&
IntPoint::operator=(const IntPoint& from)
{
x = from.x;
y = from.y;
return *this;
}
inline void
IntPoint::Set(int32 x, int32 y)
{
this->x = x;
this->y = y;
}
#endif // INT_POINT_H

272
src/servers/app/IntRect.cpp Normal file
View File

@ -0,0 +1,272 @@
/*
* Copyright 2001-2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Frans van Nispen
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "IntRect.h"
#include <stdio.h>
void
IntRect::SetLeftTop(const IntPoint& p)
{
left = p.x;
top = p.y;
}
void
IntRect::SetRightBottom(const IntPoint& p)
{
right = p.x;
bottom = p.y;
}
void
IntRect::SetLeftBottom(const IntPoint& p)
{
left = p.x;
bottom = p.y;
}
void
IntRect::SetRightTop(const IntPoint& p)
{
right = p.x;
top = p.y;
}
void
IntRect::InsetBy(const IntPoint& point)
{
left += point.x;
right -= point.x;
top += point.y;
bottom -= point.y;
}
void
IntRect::InsetBy(int32 dx, int32 dy)
{
left += dx;
right -= dx;
top += dy;
bottom -= dy;
}
IntRect&
IntRect::InsetBySelf(const IntPoint& point)
{
InsetBy(point);
return *this;
}
IntRect&
IntRect::InsetBySelf(int32 dx, int32 dy)
{
InsetBy(dx, dy);
return *this;
}
IntRect
IntRect::InsetByCopy(const IntPoint& point)
{
IntRect copy(*this);
copy.InsetBy(point);
return copy;
}
IntRect
IntRect::InsetByCopy(int32 dx, int32 dy)
{
IntRect copy(*this);
copy.InsetBy(dx, dy);
return copy;
}
void
IntRect::OffsetBy(const IntPoint& point)
{
left += point.x;
right += point.x;
top += point.y;
bottom += point.y;
}
void
IntRect::OffsetBy(int32 dx, int32 dy)
{
left += dx;
right += dx;
top += dy;
bottom += dy;
}
IntRect&
IntRect::OffsetBySelf(const IntPoint& point)
{
OffsetBy(point);
return *this;
}
IntRect&
IntRect::OffsetBySelf(int32 dx, int32 dy)
{
OffsetBy(dx, dy);
return *this;
}
IntRect
IntRect::OffsetByCopy(const IntPoint& point)
{
IntRect copy(*this);
copy.OffsetBy(point);
return copy;
}
IntRect
IntRect::OffsetByCopy(int32 dx, int32 dy)
{
IntRect copy(*this);
copy.OffsetBy(dx, dy);
return copy;
}
void
IntRect::OffsetTo(const IntPoint& point)
{
right = (right - left) + point.x;
left = point.x;
bottom = (bottom - top) + point.y;
top = point.y;
}
void
IntRect::OffsetTo(int32 x, int32 y)
{
right = (right - left) + x;
left = x;
bottom = (bottom - top) + y;
top=y;
}
IntRect&
IntRect::OffsetToSelf(const IntPoint& point)
{
OffsetTo(point);
return *this;
}
IntRect&
IntRect::OffsetToSelf(int32 dx, int32 dy)
{
OffsetTo(dx, dy);
return *this;
}
IntRect
IntRect::OffsetToCopy(const IntPoint& point)
{
IntRect copy(*this);
copy.OffsetTo(point);
return copy;
}
IntRect
IntRect::OffsetToCopy(int32 dx, int32 dy)
{
IntRect copy(*this);
copy.OffsetTo(dx, dy);
return copy;
}
void
IntRect::PrintToStream() const
{
printf("IntRect(l:%ld, t:%ld, r:%ld, b:%ld)\n", left, top, right, bottom);
}
bool
IntRect::operator==(const IntRect& rect) const
{
return left == rect.left && right == rect.right &&
top == rect.top && bottom == rect.bottom;
}
bool
IntRect::operator!=(const IntRect& rect) const
{
return !(*this == rect);
}
IntRect
IntRect::operator&(const IntRect& rect) const
{
return IntRect(max_c(left, rect.left), max_c(top, rect.top),
min_c(right, rect.right), min_c(bottom, rect.bottom));
}
IntRect
IntRect::operator|(const IntRect& rect) const
{
return IntRect(min_c(left, rect.left), min_c(top, rect.top),
max_c(right, rect.right), max_c(bottom, rect.bottom));
}
bool
IntRect::Intersects(const IntRect& rect) const
{
if (!IsValid() || !rect.IsValid())
return false;
return !(rect.left > right || rect.right < left
|| rect.top > bottom || rect.bottom < top);
}
bool
IntRect::Contains(const IntPoint& point) const
{
return point.x >= left && point.x <= right
&& point.y >= top && point.y <= bottom;
}
bool
IntRect::Contains(const IntRect& rect) const
{
return rect.left >= left && rect.right <= right
&& rect.top >= top && rect.bottom <= bottom;
}

239
src/servers/app/IntRect.h Normal file
View File

@ -0,0 +1,239 @@
/*
* Copyright 2001-2006, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Frans van Nispen
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef INT_RECT_H
#define INT_RECT_H
#include <Region.h>
#include "IntPoint.h"
class IntRect {
public:
int32 left;
int32 top;
int32 right;
int32 bottom;
IntRect();
IntRect(const IntRect& r);
IntRect(const BRect& r);
IntRect(int32 l, int32 t, int32 r, int32 b);
IntRect(const IntPoint& lt,
const IntPoint& rb);
IntRect& operator=(const IntRect &r);
void Set(int32 l, int32 t, int32 r, int32 b);
void PrintToStream() const;
IntPoint LeftTop() const;
IntPoint RightBottom() const;
IntPoint LeftBottom() const;
IntPoint RightTop() const;
void SetLeftTop(const IntPoint& p);
void SetRightBottom(const IntPoint& p);
void SetLeftBottom(const IntPoint& p);
void SetRightTop(const IntPoint& p);
// transformation
void InsetBy(const IntPoint& p);
void InsetBy(int32 dx, int32 dy);
void OffsetBy(const IntPoint& p);
void OffsetBy(int32 dx, int32 dy);
void OffsetTo(const IntPoint& p);
void OffsetTo(int32 x, int32 y);
// expression transformations
IntRect& InsetBySelf(const IntPoint& p);
IntRect& InsetBySelf(int32 dx, int32 dy);
IntRect InsetByCopy(const IntPoint& p);
IntRect InsetByCopy(int32 dx, int32 dy);
IntRect& OffsetBySelf(const IntPoint& p);
IntRect& OffsetBySelf(int32 dx, int32 dy);
IntRect OffsetByCopy(const IntPoint& p);
IntRect OffsetByCopy(int32 dx, int32 dy);
IntRect& OffsetToSelf(const IntPoint& p);
IntRect& OffsetToSelf(int32 dx, int32 dy);
IntRect OffsetToCopy(const IntPoint& p);
IntRect OffsetToCopy(int32 dx, int32 dy);
// comparison
bool operator==(const IntRect& r) const;
bool operator!=(const IntRect& r) const;
// intersection and union
IntRect operator&(const IntRect& r) const;
IntRect operator|(const IntRect& r) const;
// conversion to BRect and clipping_rect
operator clipping_rect() const;
operator BRect() const
{ return BRect(left, top,
right, bottom); }
bool Intersects(const IntRect& r) const;
bool IsValid() const;
int32 Width() const;
int32 IntegerWidth() const;
int32 Height() const;
int32 IntegerHeight() const;
bool Contains(const IntPoint& p) const;
bool Contains(const IntRect& r) const;
};
// inline definitions ----------------------------------------------------------
inline IntPoint
IntRect::LeftTop() const
{
return *(const IntPoint*)&left;
}
inline IntPoint
IntRect::RightBottom() const
{
return *(const IntPoint*)&right;
}
inline IntPoint
IntRect::LeftBottom() const
{
return IntPoint(left, bottom);
}
inline IntPoint
IntRect::RightTop() const
{
return IntPoint(right, top);
}
inline
IntRect::IntRect()
{
top = left = 0;
bottom = right = -1;
}
inline
IntRect::IntRect(int32 l, int32 t, int32 r, int32 b)
{
left = l;
top = t;
right = r;
bottom = b;
}
inline
IntRect::IntRect(const IntRect &r)
{
left = r.left;
top = r.top;
right = r.right;
bottom = r.bottom;
}
inline
IntRect::IntRect(const BRect &r)
{
left = (int32)r.left;
top = (int32)r.top;
right = (int32)r.right;
bottom = (int32)r.bottom;
}
inline
IntRect::IntRect(const IntPoint& leftTop, const IntPoint& rightBottom)
{
left = leftTop.x;
top = leftTop.y;
right = rightBottom.x;
bottom = rightBottom.y;
}
inline IntRect &
IntRect::operator=(const IntRect& from)
{
left = from.left;
top = from.top;
right = from.right;
bottom = from.bottom;
return *this;
}
inline void
IntRect::Set(int32 l, int32 t, int32 r, int32 b)
{
left = l;
top = t;
right = r;
bottom = b;
}
inline bool
IntRect::IsValid() const
{
return left <= right && top <= bottom;
}
inline int32
IntRect::IntegerWidth() const
{
return right - left;
}
inline int32
IntRect::Width() const
{
return right - left;
}
inline int32
IntRect::IntegerHeight() const
{
return bottom - top;
}
inline int32
IntRect::Height() const
{
return bottom - top;
}
inline
IntRect::operator clipping_rect() const
{
clipping_rect r;
r.left = left;
r.top = top;
r.right = right;
r.bottom = bottom;
return r;
}
#endif // INT_RECT_H

View File

@ -28,6 +28,8 @@ Server app_server :
FontManager.cpp
HashTable.cpp
InputManager.cpp
IntPoint.cpp
IntRect.cpp
MessageLooper.cpp
MultiLocker.cpp
OffscreenServerWindow.cpp

View File

@ -39,7 +39,7 @@ using std::nothrow;
void
resize_frame(BRect& frame, uint32 resizingMode, int32 x, int32 y)
resize_frame(IntRect& frame, uint32 resizingMode, int32 x, int32 y)
{
// follow with left side
if ((resizingMode & 0x0F00U) == _VIEW_RIGHT_ << 8)
@ -70,7 +70,7 @@ resize_frame(BRect& frame, uint32 resizingMode, int32 x, int32 y)
// #pragma mark -
ViewLayer::ViewLayer(BRect frame, BPoint scrollingOffset, const char* name,
ViewLayer::ViewLayer(IntRect frame, IntPoint scrollingOffset, const char* name,
int32 token, uint32 resizeMode, uint32 flags)
:
fName(name),
@ -110,11 +110,6 @@ ViewLayer::ViewLayer(BRect frame, BPoint scrollingOffset, const char* name,
fScreenClipping(),
fScreenClippingValid(false)
{
fFrame.left = float((int32)fFrame.left);
fFrame.top = float((int32)fFrame.top);
fFrame.right = float((int32)fFrame.right);
fFrame.bottom = float((int32)fFrame.bottom);
if (fDrawState)
fDrawState->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
}
@ -145,18 +140,18 @@ ViewLayer::~ViewLayer()
}
BRect
IntRect
ViewLayer::Bounds() const
{
BRect bounds(fScrollingOffset.x, fScrollingOffset.y,
fScrollingOffset.x + fFrame.Width(),
fScrollingOffset.y + fFrame.Height());
IntRect bounds(fScrollingOffset.x, fScrollingOffset.y,
fScrollingOffset.x + fFrame.Width(),
fScrollingOffset.y + fFrame.Height());
return bounds;
}
void
ViewLayer::ConvertToVisibleInTopView(BRect* bounds) const
ViewLayer::ConvertToVisibleInTopView(IntRect* bounds) const
{
*bounds = *bounds & Bounds();
// NOTE: this step is necessary even if we don't have a parent!
@ -233,11 +228,11 @@ ViewLayer::AddChild(ViewLayer* layer)
if (layer->IsVisible()) {
// trigger redraw
BRect clippedFrame = layer->Frame();
IntRect clippedFrame = layer->Frame();
ConvertToVisibleInTopView(&clippedFrame);
BRegion* dirty = fWindow->GetRegion();
if (dirty) {
dirty->Set(clippedFrame);
dirty->Set((clipping_rect)clippedFrame);
fWindow->MarkContentDirtyAsync(*dirty);
fWindow->RecycleRegion(dirty);
}
@ -288,11 +283,11 @@ ViewLayer::RemoveChild(ViewLayer* layer)
if (fVisible && layer->IsVisible()) {
// trigger redraw
BRect clippedFrame = layer->Frame();
IntRect clippedFrame = layer->Frame();
ConvertToVisibleInTopView(&clippedFrame);
BRegion* dirty = fWindow->GetRegion();
if (dirty) {
dirty->Set(clippedFrame);
dirty->Set((clipping_rect)clippedFrame);
fWindow->MarkContentDirtyAsync(*dirty);
fWindow->RecycleRegion(dirty);
}
@ -303,34 +298,6 @@ ViewLayer::RemoveChild(ViewLayer* layer)
}
ViewLayer*
ViewLayer::FirstChild() const
{
return fFirstChild;
}
ViewLayer*
ViewLayer::PreviousSibling() const
{
return fPreviousSibling;
}
ViewLayer*
ViewLayer::NextSibling() const
{
return fNextSibling;
}
ViewLayer*
ViewLayer::LastChild() const
{
return fLastChild;
}
ViewLayer*
ViewLayer::TopLayer()
{
@ -404,13 +371,6 @@ ViewLayer::SetFlags(uint32 flags)
}
BPoint
ViewLayer::ScrollingOffset() const
{
return fScrollingOffset;
}
void
ViewLayer::SetDrawingOrigin(BPoint origin)
{
@ -464,8 +424,8 @@ ViewLayer::SetUserClipping(const BRegion* region)
void
ViewLayer::SetViewBitmap(ServerBitmap* bitmap, BRect sourceRect,
BRect destRect, int32 resizingMode, int32 options)
ViewLayer::SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect,
IntRect destRect, int32 resizingMode, int32 options)
{
if (fViewBitmap != NULL) {
Overlay* overlay = _Overlay();
@ -492,13 +452,6 @@ ViewLayer::SetViewBitmap(ServerBitmap* bitmap, BRect sourceRect,
fBitmapResizingMode = resizingMode;
fBitmapOptions = options;
// round off destination rect to avoid problems
// with drawing the view color around the bitmap
fBitmapDestination.OffsetTo(roundf(fBitmapDestination.left),
roundf(fBitmapDestination.top));
fBitmapDestination.right = roundf(fBitmapDestination.right);
fBitmapDestination.bottom = roundf(fBitmapDestination.bottom);
_UpdateOverlayView();
}
@ -520,7 +473,7 @@ ViewLayer::_UpdateOverlayView() const
if (overlay == NULL)
return;
BRect destination = fBitmapDestination;
IntRect destination = fBitmapDestination;
ConvertToScreen(&destination);
overlay->Configure(fBitmapSource, destination);
@ -561,6 +514,15 @@ ViewLayer::ConvertToParent(BPoint* point) const
}
void
ViewLayer::ConvertToParent(IntPoint* point) const
{
// remove scrolling offset and convert to parent coordinate space
point->x += fFrame.left - fScrollingOffset.x;
point->y += fFrame.top - fScrollingOffset.y;
}
void
ViewLayer::ConvertToParent(BRect* rect) const
{
@ -570,6 +532,15 @@ ViewLayer::ConvertToParent(BRect* rect) const
}
void
ViewLayer::ConvertToParent(IntRect* rect) const
{
// remove scrolling offset and convert to parent coordinate space
rect->OffsetBy(fFrame.left - fScrollingOffset.x,
fFrame.top - fScrollingOffset.y);
}
void
ViewLayer::ConvertToParent(BRegion* region) const
{
@ -582,7 +553,16 @@ ViewLayer::ConvertToParent(BRegion* region) const
void
ViewLayer::ConvertFromParent(BPoint* point) const
{
// remove scrolling offset and convert to parent coordinate space
// convert from parent coordinate space amd add scrolling offset
point->x += fScrollingOffset.x - fFrame.left;
point->y += fScrollingOffset.y - fFrame.top;
}
void
ViewLayer::ConvertFromParent(IntPoint* point) const
{
// convert from parent coordinate space amd add scrolling offset
point->x += fScrollingOffset.x - fFrame.left;
point->y += fScrollingOffset.y - fFrame.top;
}
@ -591,7 +571,16 @@ ViewLayer::ConvertFromParent(BPoint* point) const
void
ViewLayer::ConvertFromParent(BRect* rect) const
{
// remove scrolling offset and convert to parent coordinate space
// convert from parent coordinate space amd add scrolling offset
rect->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
void
ViewLayer::ConvertFromParent(IntRect* rect) const
{
// convert from parent coordinate space amd add scrolling offset
rect->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
@ -600,7 +589,7 @@ ViewLayer::ConvertFromParent(BRect* rect) const
void
ViewLayer::ConvertFromParent(BRegion* region) const
{
// remove scrolling offset and convert to parent coordinate space
// convert from parent coordinate space amd add scrolling offset
region->OffsetBy(fScrollingOffset.x - fFrame.left,
fScrollingOffset.y - fFrame.top);
}
@ -616,6 +605,17 @@ ViewLayer::ConvertToScreen(BPoint* pt) const
}
//! converts a point from local to screen coordinate system
void
ViewLayer::ConvertToScreen(IntPoint* pt) const
{
ConvertToParent(pt);
if (fParent)
fParent->ConvertToScreen(pt);
}
//! converts a rect from local to screen coordinate system
void
ViewLayer::ConvertToScreen(BRect* rect) const
@ -627,6 +627,17 @@ ViewLayer::ConvertToScreen(BRect* rect) const
}
//! converts a rect from local to screen coordinate system
void
ViewLayer::ConvertToScreen(IntRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertToScreen(&offset);
rect->OffsetBy(offset);
}
//! converts a region from local to screen coordinate system
void
ViewLayer::ConvertToScreen(BRegion* region) const
@ -649,6 +660,17 @@ ViewLayer::ConvertFromScreen(BPoint* pt) const
}
//! converts a point from screen to local coordinate system
void
ViewLayer::ConvertFromScreen(IntPoint* pt) const
{
ConvertFromParent(pt);
if (fParent)
fParent->ConvertFromScreen(pt);
}
//! converts a rect from screen to local coordinate system
void
ViewLayer::ConvertFromScreen(BRect* rect) const
@ -660,6 +682,17 @@ ViewLayer::ConvertFromScreen(BRect* rect) const
}
//! converts a rect from screen to local coordinate system
void
ViewLayer::ConvertFromScreen(IntRect* rect) const
{
BPoint offset(0.0, 0.0);
ConvertFromScreen(&offset);
rect->OffsetBy(offset.x, offset.y);
}
//! converts a region from screen to local coordinate system
void
ViewLayer::ConvertFromScreen(BRegion* region) const
@ -729,26 +762,26 @@ ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
#if 1
// based on redraw on new location
// the place were we are now visible
BRect newVisibleBounds = Bounds();
IntRect newVisibleBounds(Bounds());
// we can use the frame of the old
// local clipping to see which parts need invalidation
BRect oldVisibleBounds(Bounds());
IntRect oldVisibleBounds(newVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToScreen(&oldVisibleBounds);
ConvertToVisibleInTopView(&newVisibleBounds);
dirtyRegion->Include(oldVisibleBounds);
dirtyRegion->Include((clipping_rect)oldVisibleBounds);
// newVisibleBounds already is in screen coords
dirtyRegion->Include(newVisibleBounds);
dirtyRegion->Include((clipping_rect)newVisibleBounds);
#else
// blitting version, invalidates
// old contents
BRect oldVisibleBounds(Bounds());
IntRect oldVisibleBounds(Bounds());
IntRect newVisibleBounds(oldVisibleBounds);
oldVisibleBounds.OffsetBy(-x, -y);
ConvertToScreen(&oldVisibleBounds);
BRect newVisibleBounds(Bounds());
// NOTE: using ConvertToVisibleInTopView()
// instead of ConvertToScreen()! see below
ConvertToVisibleInTopView(&newVisibleBounds);
@ -765,7 +798,7 @@ ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
region->Set(oldVisibleBounds);
newVisibleBounds.OffsetBy(x, y);
region->Exclude(newVisibleBounds);
region->Exclude((clipping_rect)newVisibleBounds);
dirtyRegion->Include(dirty);
fWindow->RecycleRegion(region);
@ -784,7 +817,7 @@ ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
// the parent, or might now be hidden underneath
// the parent, this is taken care of when building
// the screen clipping
InvalidateScreenClipping(true);
InvalidateScreenClipping();
}
}
@ -799,7 +832,7 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
fFrame.bottom += y;
if (fVisible && dirtyRegion) {
BRect oldBounds(Bounds());
IntRect oldBounds(Bounds());
oldBounds.right -= x;
oldBounds.bottom -= y;
@ -807,25 +840,25 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
if (!dirty)
return;
dirty->Set(Bounds());
dirty->Include(oldBounds);
dirty->Set((clipping_rect)Bounds());
dirty->Include((clipping_rect)oldBounds);
if (!(fFlags & B_FULL_UPDATE_ON_RESIZE)) {
// the dirty region is just the difference of
// old and new bounds
dirty->Exclude(oldBounds & Bounds());
dirty->Exclude((clipping_rect)(oldBounds & Bounds()));
}
InvalidateScreenClipping(true);
InvalidateScreenClipping();
if (dirty->CountRects() > 0) {
// exclude children, they are expected to
// include their own dirty regions in ParentResized()
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
if (child->IsVisible()) {
BRect previousChildVisible(child->Frame() & oldBounds & Bounds());
IntRect previousChildVisible(child->Frame() & oldBounds & Bounds());
if (dirty->Frame().Intersects(previousChildVisible)) {
dirty->Exclude(previousChildVisible);
dirty->Exclude((clipping_rect)previousChildVisible);
}
}
}
@ -855,7 +888,7 @@ ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
void
ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
{
BRect newFrame = fFrame;
IntRect newFrame = fFrame;
resize_frame(newFrame, fResizeMode & 0x0000ffff, x, y);
if (newFrame != fFrame) {
@ -878,10 +911,10 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
// old contents
// remember old bounds for tracking dirty region
BRect oldBounds(Bounds());
IntRect oldBounds(Bounds());
// find the area of the view that can be scrolled,
// contents are shifted in the opposite direction from scrolling
BRect stillVisibleBounds(oldBounds);
IntRect stillVisibleBounds(oldBounds);
stillVisibleBounds.OffsetBy(x, y);
// NOTE: using ConvertToVisibleInTopView()
@ -900,7 +933,7 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
BRegion* copyRegion = fWindow->GetRegion();
if (!copyRegion)
return;
copyRegion->Set(stillVisibleBounds);
copyRegion->Set((clipping_rect)stillVisibleBounds);
fWindow->CopyContents(copyRegion, -x, -y);
// find the dirty region as far as we are
@ -908,22 +941,22 @@ ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
BRegion* dirty = copyRegion;
// reuse copyRegion and call it dirty
dirty->Set(oldBounds);
dirty->Set((clipping_rect)oldBounds);
stillVisibleBounds.OffsetBy(-x, -y);
dirty->Exclude(stillVisibleBounds);
dirty->Exclude((clipping_rect)stillVisibleBounds);
dirtyRegion->Include(dirty);
fWindow->RecycleRegion(dirty);
// the screen clipping of this view and it's
// childs is no longer valid
InvalidateScreenClipping(true);
InvalidateScreenClipping();
RebuildClipping(false);
}
void
ViewLayer::CopyBits(BRect src, BRect dst, BRegion& windowContentClipping)
ViewLayer::CopyBits(IntRect src, IntRect dst, BRegion& windowContentClipping)
{
if (!fVisible || !fWindow)
return;
@ -932,14 +965,14 @@ ViewLayer::CopyBits(BRect src, BRect dst, BRegion& windowContentClipping)
// blitting version
int32 xOffset = (int32)(dst.left - src.left);
int32 yOffset = (int32)(dst.top - src.top);
int32 xOffset = dst.left - src.left;
int32 yOffset = dst.top - src.top;
// figure out which part can be blittet
BRect visibleSrc(src);
IntRect visibleSrc(src);
ConvertToVisibleInTopView(&visibleSrc);
BRect visibleSrcAtDest(src);
IntRect visibleSrcAtDest(src);
visibleSrcAtDest.OffsetBy(xOffset, yOffset);
ConvertToVisibleInTopView(&visibleSrcAtDest);
@ -963,7 +996,7 @@ ViewLayer::CopyBits(BRect src, BRect dst, BRegion& windowContentClipping)
// the reason for this is that we are not supposed to visually
// copy children in the source rect and neither to copy onto
// children in the destination rect...
copyRegion->Set(visibleSrc);
copyRegion->Set((clipping_rect)visibleSrc);
copyRegion->IntersectWith(&ScreenClipping(&windowContentClipping));
// note that fScreenClipping is used directly from hereon
// because it is now up to date
@ -975,7 +1008,7 @@ ViewLayer::CopyBits(BRect src, BRect dst, BRegion& windowContentClipping)
fWindow->CopyContents(copyRegion, xOffset, yOffset);
// find the dirty region as far as we are concerned
BRect dirtyDst(dst);
IntRect dirtyDst(dst);
ConvertToVisibleInTopView(&dirtyDst);
BRegion* dirty = fWindow->GetRegion();
@ -987,7 +1020,7 @@ ViewLayer::CopyBits(BRect src, BRect dst, BRegion& windowContentClipping)
// offset copyRegion to destination again
copyRegion->OffsetBy(xOffset, yOffset);
// start with destination given by user
dirty->Set(dirtyDst);
dirty->Set((clipping_rect)dirtyDst);
// exclude the part that we could copy
dirty->Exclude(copyRegion);
@ -1238,12 +1271,12 @@ ViewLayer::SetHidden(bool hidden)
if (fWindow) {
// trigger a redraw
BRect clippedBounds = Bounds();
IntRect clippedBounds = Bounds();
ConvertToVisibleInTopView(&clippedBounds);
BRegion* dirty = fWindow->GetRegion();
if (!dirty)
return;
dirty->Set(clippedBounds);
dirty->Set((clipping_rect)clippedBounds);
fWindow->MarkContentDirty(*dirty);
fWindow->RecycleRegion(dirty);
}
@ -1287,6 +1320,8 @@ ViewLayer::UpdateVisibleDeep(bool parentVisible)
void
ViewLayer::MarkBackgroundDirty()
{
if (fBackgroundDirty)
return;
fBackgroundDirty = true;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling())
child->MarkBackgroundDirty();
@ -1332,8 +1367,8 @@ ViewLayer::PrintToStream() const
{
printf("ViewLayer: %s\n", Name());
printf(" fToken: %ld\n", fToken);
printf(" fFrame: BRect(%.1f, %.1f, %.1f, %.1f)\n", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
printf(" fScrollingOffset: BPoint(%.1f, %.1f)\n", fScrollingOffset.x, fScrollingOffset.y);
printf(" fFrame: IntRect(%ld, %ld, %ld, %ld)\n", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
printf(" fScrollingOffset: IntPoint(%ld, %ld)\n", fScrollingOffset.x, fScrollingOffset.y);
printf(" fHidden: %d\n", fHidden);
printf(" fVisible: %d\n", fVisible);
printf(" fWindow: %p\n", fWindow);
@ -1355,12 +1390,12 @@ void
ViewLayer::RebuildClipping(bool deep)
{
// the clipping spans over the bounds area
fLocalClipping.Set(Bounds());
fLocalClipping.Set((clipping_rect)Bounds());
// exclude all childs from the clipping
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
if (child->IsVisible())
fLocalClipping.Exclude(child->Frame());
fLocalClipping.Exclude((clipping_rect)child->Frame());
if (deep)
child->RebuildClipping(deep);
@ -1395,13 +1430,13 @@ ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
// see if we parts of our bounds are hidden underneath
// the parent, the local clipping does not account for this
BRect clippedBounds = Bounds();
IntRect clippedBounds = Bounds();
ConvertToVisibleInTopView(&clippedBounds);
if (clippedBounds.Width() < fScreenClipping.Frame().Width() ||
clippedBounds.Height() < fScreenClipping.Frame().Height()) {
BRegion* temp = fWindow->GetRegion();
if (temp) {
temp->Set(clippedBounds);
temp->Set((clipping_rect)clippedBounds);
fScreenClipping.IntersectWith(temp);
fWindow->RecycleRegion(temp);
}
@ -1417,14 +1452,15 @@ ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
void
ViewLayer::InvalidateScreenClipping(bool deep)
ViewLayer::InvalidateScreenClipping()
{
if (!fScreenClippingValid)
return;
fScreenClippingValid = false;
if (deep) {
// invalidate the childrens screen clipping as well
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->InvalidateScreenClipping(deep);
}
// invalidate the childrens screen clipping as well
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->InvalidateScreenClipping();
}
}

View File

@ -13,6 +13,7 @@
#include "RGBColor.h"
#include "IntRect.h"
#include <GraphicsDefs.h>
#include <Region.h>
@ -34,7 +35,7 @@ class ServerPicture;
class ViewLayer {
public:
ViewLayer(BRect frame, BPoint scrollingOffset,
ViewLayer(IntRect frame, IntPoint scrollingOffset,
const char* name, int32 token, uint32 resizeMode,
uint32 flags);
@ -43,9 +44,9 @@ class ViewLayer {
int32 Token() const
{ return fToken; }
BRect Frame() const
IntRect Frame() const
{ return fFrame; }
BRect Bounds() const;
IntRect Bounds() const;
void SetResizeMode(uint32 resizeMode)
{ fResizeMode = resizeMode; }
@ -58,7 +59,8 @@ class ViewLayer {
uint32 Flags() const
{ return fFlags; }
BPoint ScrollingOffset() const;
inline IntPoint ScrollingOffset() const
{ return fScrollingOffset; }
void SetDrawingOrigin(BPoint origin);
BPoint DrawingOrigin() const;
@ -71,7 +73,7 @@ class ViewLayer {
// converts the given frame up the view hierarchy and
// clips to each views bounds
void ConvertToVisibleInTopView(BRect* bounds) const;
void ConvertToVisibleInTopView(IntRect* bounds) const;
void AttachedToWindow(WindowLayer* window);
void DetachedFromWindow();
@ -84,10 +86,14 @@ class ViewLayer {
inline ViewLayer* Parent() const
{ return fParent; }
ViewLayer* FirstChild() const;
ViewLayer* LastChild() const;
ViewLayer* PreviousSibling() const;
ViewLayer* NextSibling() const;
inline ViewLayer* FirstChild() const
{ return fFirstChild; }
inline ViewLayer* LastChild() const
{ return fLastChild; }
inline ViewLayer* PreviousSibling() const
{ return fPreviousSibling; }
inline ViewLayer* NextSibling() const
{ return fNextSibling; }
ViewLayer* TopLayer();
@ -99,19 +105,27 @@ class ViewLayer {
// coordinate conversion
void ConvertToParent(BPoint* point) const;
void ConvertToParent(IntPoint* point) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(IntRect* rect) const;
void ConvertToParent(BRegion* region) const;
void ConvertFromParent(BPoint* point) const;
void ConvertFromParent(IntPoint* point) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(IntRect* rect) const;
void ConvertFromParent(BRegion* region) const;
void ConvertToScreen(BPoint* point) const;
void ConvertToScreen(IntPoint* point) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(IntRect* rect) const;
void ConvertToScreen(BRegion* region) const;
void ConvertFromScreen(BPoint* point) const;
void ConvertFromScreen(IntPoint* point) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(IntRect* rect) const;
void ConvertFromScreen(BRegion* region) const;
void ConvertToScreenForDrawing(BPoint* point) const;
@ -133,7 +147,7 @@ class ViewLayer {
void ParentResized(int32 dx, int32 dy,
BRegion* dirtyRegion);
void CopyBits(BRect src, BRect dst,
void CopyBits(IntRect src, IntRect dst,
BRegion& windowContentClipping);
const BRegion& LocalClipping() const { return fLocalClipping; }
@ -147,8 +161,8 @@ class ViewLayer {
ServerBitmap* ViewBitmap() const
{ return fViewBitmap; }
void SetViewBitmap(ServerBitmap* bitmap, BRect sourceRect,
BRect destRect, int32 resizingMode, int32 options);
void SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect,
IntRect destRect, int32 resizingMode, int32 options);
void PushState();
void PopState();
@ -207,8 +221,8 @@ class ViewLayer {
void RebuildClipping(bool deep);
BRegion& ScreenClipping(BRegion* windowContentClipping,
bool force = false) const;
void InvalidateScreenClipping(bool deep);
bool IsScreenClippingValid() const
void InvalidateScreenClipping();
inline bool IsScreenClippingValid() const
{ return fScreenClippingValid; }
// debugging
@ -223,15 +237,15 @@ class ViewLayer {
BString fName;
int32 fToken;
// area within parent coordinate space
BRect fFrame;
IntRect fFrame;
// scrolling offset
BPoint fScrollingOffset;
IntPoint fScrollingOffset;
RGBColor fViewColor;
DrawState* fDrawState;
ServerBitmap* fViewBitmap;
BRect fBitmapSource;
BRect fBitmapDestination;
IntRect fBitmapSource;
IntRect fBitmapDestination;
int32 fBitmapResizingMode;
int32 fBitmapOptions;
@ -264,4 +278,5 @@ class ViewLayer {
};
#endif // LAYER_H

View File

@ -20,8 +20,8 @@ UseFreeTypeHeaders ;
local defines = [ FDefines TEST_MODE=1 ] ;
# USE_DIRECT_WINDOW_TEST_MODE=1
SubDirCcFlags $(defines) ; #-fcheck-memory-usage -D_NO_INLINE_ASM ;
SubDirC++Flags $(defines) ; #-fcheck-memory-usage -D_NO_INLINE_ASM ;
SubDirCcFlags $(defines) ; #-finstrument-functions ; #-fcheck-memory-usage -D_NO_INLINE_ASM ;
SubDirC++Flags $(defines) ; #-finstrument-functions ; #-fcheck-memory-usage -D_NO_INLINE_ASM ;
SEARCH_SOURCE += $(appServerDir) [ FDirName $(appServerDir) drawing ] ;
@ -46,6 +46,7 @@ SharedLibrary libhwinterfaceimpl.so :
DWindowHWInterface.cpp
MultiLocker.cpp
# trace.c
: be libhwinterface.so
;
@ -60,6 +61,8 @@ SharedLibrary libhaikuappserver.so :
FontFamily.cpp
FontManager.cpp
HashTable.cpp
IntPoint.cpp
IntRect.cpp
MultiLocker.cpp
Overlay.cpp
RGBColor.cpp
@ -71,6 +74,8 @@ SharedLibrary libhaikuappserver.so :
# drawing
PatternHandler.cpp
# trace.c
# libraries
: be libtextencoding.so libfreetype.so
;