Looks like I deleted too much... copied Region.h back from the os
folder, updated Region.cpp and RegionSupport.cpp accordingly. Also implemented empty BStatable destructor. Needed, since it's virtual now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22713 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007, Haiku. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _REGION_H
|
||||||
|
#define _REGION_H
|
||||||
|
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
class ServerLink;
|
||||||
|
class LinkReceiver;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Integer rect used to define a clipping rectangle. All bounds are inclusive. */
|
||||||
|
/* Moved from DirectWindow.h */
|
||||||
|
typedef struct {
|
||||||
|
int32 left;
|
||||||
|
int32 top;
|
||||||
|
int32 right;
|
||||||
|
int32 bottom;
|
||||||
|
} clipping_rect;
|
||||||
|
|
||||||
|
|
||||||
|
class BRegion {
|
||||||
|
public:
|
||||||
|
BRegion();
|
||||||
|
BRegion(const BRegion& region);
|
||||||
|
BRegion(const BRect rect);
|
||||||
|
virtual ~BRegion();
|
||||||
|
|
||||||
|
BRegion &operator=(const BRegion &from);
|
||||||
|
|
||||||
|
void Set(BRect newBounds);
|
||||||
|
void Set(clipping_rect newBounds);
|
||||||
|
|
||||||
|
BRect Frame() const;
|
||||||
|
clipping_rect FrameInt() const;
|
||||||
|
|
||||||
|
BRect RectAt(int32 index) /*const*/;
|
||||||
|
clipping_rect RectAtInt(int32 index) /*const*/;
|
||||||
|
|
||||||
|
int32 CountRects() /*const*/;
|
||||||
|
|
||||||
|
bool Intersects(BRect rect) const;
|
||||||
|
bool Intersects(clipping_rect rect) const;
|
||||||
|
|
||||||
|
bool Contains(BPoint point) const;
|
||||||
|
bool Contains(int32 x, int32 y) /*const*/;
|
||||||
|
|
||||||
|
void PrintToStream() const;
|
||||||
|
|
||||||
|
void OffsetBy(int32 x, int32 y);
|
||||||
|
|
||||||
|
void MakeEmpty();
|
||||||
|
|
||||||
|
void Include(BRect rect);
|
||||||
|
void Include(clipping_rect rect);
|
||||||
|
void Include(const BRegion*);
|
||||||
|
|
||||||
|
void Exclude(BRect r);
|
||||||
|
void Exclude(clipping_rect r);
|
||||||
|
void Exclude(const BRegion* region);
|
||||||
|
|
||||||
|
void IntersectWith(const BRegion* region);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class BDirectWindow;
|
||||||
|
friend class BPrivate::ServerLink;
|
||||||
|
friend class BPrivate::LinkReceiver;
|
||||||
|
|
||||||
|
class Support;
|
||||||
|
friend class Support;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BRegion(const clipping_rect& rect);
|
||||||
|
|
||||||
|
void _AdoptRegionData(BRegion& region);
|
||||||
|
bool _SetSize(long newSize);
|
||||||
|
|
||||||
|
clipping_rect _Convert(const BRect& rect) const;
|
||||||
|
clipping_rect _ConvertToInternal(const BRect& rect) const;
|
||||||
|
clipping_rect _ConvertToInternal(
|
||||||
|
const clipping_rect& rect) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
long fCount;
|
||||||
|
long fDataSize;
|
||||||
|
clipping_rect fBounds;
|
||||||
|
clipping_rect* fData;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _REGION_H
|
||||||
@@ -1,65 +1,37 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2003-2005, Haiku, Inc.
|
* Copyright 2003-2007, Haiku. All rights reserved.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Stefano Ceccherini ([email protected])
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* Stephan Aßmus <[email protected]>
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
*/
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// File Name: Region.cpp
|
|
||||||
// Author: Stefano Ceccherini ([email protected])
|
|
||||||
// Description: Region class consisting of multiple rectangles
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Notes: As now, memory is always allocated and never freed (except on destruction,
|
|
||||||
// or sometimes when a copy is made).
|
|
||||||
// This let us be a bit faster since we don't do many reallocations.
|
|
||||||
// But that means that even an empty region could "waste" much space, if it contained
|
|
||||||
// many rects before being emptied.
|
|
||||||
// I.E: a region which contains 24 rects allocates more than 24 * 4 * sizeof(int32)
|
|
||||||
// = 96 * sizeof(int32) bytes. If we call MakeEmpty(), that region will contain no rects,
|
|
||||||
// but it will still keep the allocated memory.
|
|
||||||
// This shouldnt' be an issue, since usually BRegions are just used for calculations,
|
|
||||||
// and don't last so long.
|
|
||||||
// Anyway, we can change that behaviour if we want, but BeOS's BRegion seems to behave exactly
|
|
||||||
// like this.
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <Debug.h>
|
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
|
|
||||||
#include <clipping.h>
|
#include <malloc.h>
|
||||||
#include <RegionSupport.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
#include "clipping.h"
|
||||||
|
#include "RegionSupport.h"
|
||||||
|
|
||||||
|
|
||||||
|
const static int32 kDataBlockSize = 8;
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Initializes a region. The region will have no rects,
|
/*! \brief Initializes a region. The region will have no rects,
|
||||||
and its bound will be invalid.
|
and its fBounds will be invalid.
|
||||||
*/
|
*/
|
||||||
BRegion::BRegion()
|
BRegion::BRegion()
|
||||||
:
|
: fCount(0)
|
||||||
data_size(8),
|
, fDataSize(0)
|
||||||
data(NULL)
|
, fBounds((clipping_rect){ 0, 0, 0, 0 })
|
||||||
|
, fData(NULL)
|
||||||
{
|
{
|
||||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
_SetSize(kDataBlockSize);
|
||||||
|
|
||||||
Support::ZeroRegion(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,19 +39,12 @@ BRegion::BRegion()
|
|||||||
\param region The region to copy.
|
\param region The region to copy.
|
||||||
*/
|
*/
|
||||||
BRegion::BRegion(const BRegion& region)
|
BRegion::BRegion(const BRegion& region)
|
||||||
:
|
: fCount(0)
|
||||||
data(NULL)
|
, fDataSize(0)
|
||||||
|
, fBounds((clipping_rect){ 0, 0, 0, 0 })
|
||||||
|
, fData(NULL)
|
||||||
{
|
{
|
||||||
bound = region.bound;
|
*this = region;
|
||||||
count = region.count;
|
|
||||||
data_size = region.data_size;
|
|
||||||
|
|
||||||
if (data_size <= 0)
|
|
||||||
data_size = 1;
|
|
||||||
|
|
||||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
|
||||||
|
|
||||||
memcpy(data, region.data, count * sizeof(clipping_rect));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -87,13 +52,29 @@ BRegion::BRegion(const BRegion ®ion)
|
|||||||
\param rect The BRect to set the region to.
|
\param rect The BRect to set the region to.
|
||||||
*/
|
*/
|
||||||
BRegion::BRegion(const BRect rect)
|
BRegion::BRegion(const BRect rect)
|
||||||
:
|
: fCount(0)
|
||||||
data_size(8),
|
, fDataSize(1)
|
||||||
data(NULL)
|
, fBounds((clipping_rect){ 0, 0, 0, 0 })
|
||||||
|
, fData(&fBounds)
|
||||||
{
|
{
|
||||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
if (!rect.IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
Set(rect);
|
fBounds = _ConvertToInternal(rect);
|
||||||
|
fCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: private constructor
|
||||||
|
/*! \brief Initializes a region to contain a clipping_rect.
|
||||||
|
\param rect The clipping_rect to set the region to, already in
|
||||||
|
internal rect format.
|
||||||
|
*/
|
||||||
|
BRegion::BRegion(const clipping_rect& rect)
|
||||||
|
: fCount(1)
|
||||||
|
, fDataSize(1)
|
||||||
|
, fBounds(rect)
|
||||||
|
, fData(&fBounds)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,68 +82,34 @@ BRegion::BRegion(const BRect rect)
|
|||||||
*/
|
*/
|
||||||
BRegion::~BRegion()
|
BRegion::~BRegion()
|
||||||
{
|
{
|
||||||
free(data);
|
if (fData != &fBounds)
|
||||||
|
free(fData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Returns the bounds of the region.
|
// #pragma mark -
|
||||||
\return A BRect which represents the bounds of the region.
|
|
||||||
|
|
||||||
|
/*! \brief Modifies the region to be a copy of the given BRegion.
|
||||||
|
\param region the BRegion to copy.
|
||||||
|
\return This function always returns \c *this.
|
||||||
*/
|
*/
|
||||||
BRect
|
BRegion &
|
||||||
BRegion::Frame() const
|
BRegion::operator=(const BRegion ®ion)
|
||||||
{
|
{
|
||||||
return to_BRect(bound);
|
if (®ion == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
// handle reallocation if we're too small to contain
|
||||||
|
// the other region
|
||||||
|
if (_SetSize(region.fDataSize)) {
|
||||||
|
memcpy(fData, region.fData, region.fCount * sizeof(clipping_rect));
|
||||||
|
|
||||||
|
fBounds = region.fBounds;
|
||||||
|
fCount = region.fCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
/*! \brief Returns the bounds of the region as a clipping_rect (which has integer coordinates).
|
|
||||||
\return A clipping_rect which represents the bounds of the region.
|
|
||||||
*/
|
|
||||||
clipping_rect
|
|
||||||
BRegion::FrameInt() const
|
|
||||||
{
|
|
||||||
return bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Returns the regions's BRect at the given index.
|
|
||||||
\param index The index (zero based) of the wanted rectangle.
|
|
||||||
\return If the given index is valid, it returns the BRect at that index,
|
|
||||||
otherwise, it returns an invalid BRect.
|
|
||||||
*/
|
|
||||||
BRect
|
|
||||||
BRegion::RectAt(int32 index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < count)
|
|
||||||
return to_BRect(data[index]);
|
|
||||||
|
|
||||||
return BRect(); //An invalid BRect
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Returns the regions's clipping_rect at the given index.
|
|
||||||
\param index The index (zero based) of the wanted rectangle.
|
|
||||||
\return If the given index is valid, it returns the clipping_rect at that index,
|
|
||||||
otherwise, it returns an invalid clipping_rect.
|
|
||||||
*/
|
|
||||||
clipping_rect
|
|
||||||
BRegion::RectAtInt(int32 index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < count)
|
|
||||||
return data[index];
|
|
||||||
|
|
||||||
clipping_rect rect = { 1, 1, 0, 0 };
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Counts the region rects.
|
|
||||||
\return An int32 which is the total number of rects in the region.
|
|
||||||
*/
|
|
||||||
int32
|
|
||||||
BRegion::CountRects()
|
|
||||||
{
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,7 +119,7 @@ BRegion::CountRects()
|
|||||||
void
|
void
|
||||||
BRegion::Set(BRect newBounds)
|
BRegion::Set(BRect newBounds)
|
||||||
{
|
{
|
||||||
Set(to_clipping_rect(newBounds));
|
Set(_Convert(newBounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -182,17 +129,93 @@ BRegion::Set(BRect newBounds)
|
|||||||
void
|
void
|
||||||
BRegion::Set(clipping_rect newBounds)
|
BRegion::Set(clipping_rect newBounds)
|
||||||
{
|
{
|
||||||
ASSERT(data_size > 0);
|
_SetSize(1);
|
||||||
|
|
||||||
if (valid_rect(newBounds)) {
|
if (valid_rect(newBounds) && fData) {
|
||||||
count = 1;
|
fCount = 1;
|
||||||
data[0] = newBounds;
|
// cheap convert to internal rect format
|
||||||
bound = newBounds;
|
newBounds.right++;
|
||||||
|
newBounds.bottom++;
|
||||||
|
fData[0] = fBounds = newBounds;
|
||||||
} else
|
} else
|
||||||
Support::ZeroRegion(*this);
|
MakeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Returns the bounds of the region.
|
||||||
|
\return A BRect which represents the bounds of the region.
|
||||||
|
*/
|
||||||
|
BRect
|
||||||
|
BRegion::Frame() const
|
||||||
|
{
|
||||||
|
return BRect(fBounds.left, fBounds.top,
|
||||||
|
fBounds.right - 1, fBounds.bottom - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Returns the bounds of the region as a clipping_rect (which has integer coordinates).
|
||||||
|
\return A clipping_rect which represents the bounds of the region.
|
||||||
|
*/
|
||||||
|
clipping_rect
|
||||||
|
BRegion::FrameInt() const
|
||||||
|
{
|
||||||
|
return (clipping_rect){ fBounds.left, fBounds.top,
|
||||||
|
fBounds.right - 1, fBounds.bottom - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Returns the regions's BRect at the given index.
|
||||||
|
\param index The index (zero based) of the wanted rectangle.
|
||||||
|
\return If the given index is valid, it returns the BRect at that index,
|
||||||
|
otherwise, it returns an invalid BRect.
|
||||||
|
*/
|
||||||
|
BRect
|
||||||
|
BRegion::RectAt(int32 index) /*const*/
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < fCount) {
|
||||||
|
const clipping_rect& r = fData[index];
|
||||||
|
return BRect(r.left, r.top, r.right - 1, r.bottom - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BRect();
|
||||||
|
// an invalid BRect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Returns the regions's clipping_rect at the given index.
|
||||||
|
\param index The index (zero based) of the wanted rectangle.
|
||||||
|
\return If the given index is valid, it returns the clipping_rect at that index,
|
||||||
|
otherwise, it returns an invalid clipping_rect.
|
||||||
|
*/
|
||||||
|
clipping_rect
|
||||||
|
BRegion::RectAtInt(int32 index) /*const*/
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < fCount) {
|
||||||
|
const clipping_rect& r = fData[index];
|
||||||
|
return (clipping_rect){ r.left, r.top, r.right - 1, r.bottom - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return (clipping_rect){ 1, 1, 0, 0 };
|
||||||
|
// an invalid clipping_rect
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Counts the region rects.
|
||||||
|
\return An int32 which is the total number of rects in the region.
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
BRegion::CountRects() /*const*/
|
||||||
|
{
|
||||||
|
return fCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Check if the region has any area in common with the given BRect.
|
/*! \brief Check if the region has any area in common with the given BRect.
|
||||||
\param rect The BRect to check the region against to.
|
\param rect The BRect to check the region against to.
|
||||||
\return \ctrue if the region has any area in common with the BRect, \cfalse if not.
|
\return \ctrue if the region has any area in common with the BRect, \cfalse if not.
|
||||||
@@ -200,7 +223,7 @@ BRegion::Set(clipping_rect newBounds)
|
|||||||
bool
|
bool
|
||||||
BRegion::Intersects(BRect rect) const
|
BRegion::Intersects(BRect rect) const
|
||||||
{
|
{
|
||||||
return Intersects(to_clipping_rect(rect));
|
return Intersects(_Convert(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -211,15 +234,13 @@ BRegion::Intersects(BRect rect) const
|
|||||||
bool
|
bool
|
||||||
BRegion::Intersects(clipping_rect rect) const
|
BRegion::Intersects(clipping_rect rect) const
|
||||||
{
|
{
|
||||||
if (!rects_intersect(rect, bound))
|
// cheap convert to internal rect format
|
||||||
return false;
|
rect.right ++;
|
||||||
|
rect.bottom ++;
|
||||||
|
|
||||||
for (long c = 0; c < count; c++) {
|
int result = Support::XRectInRegion(this, rect);
|
||||||
if (rects_intersect(data[c], rect))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return result > Support::RectangleOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -228,18 +249,9 @@ BRegion::Intersects(clipping_rect rect) const
|
|||||||
\return \ctrue if the region contains the BPoint, \cfalse if not.
|
\return \ctrue if the region contains the BPoint, \cfalse if not.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
BRegion::Contains(BPoint pt) const
|
BRegion::Contains(BPoint point) const
|
||||||
{
|
{
|
||||||
// If the point doesn't lie within the region's bounds,
|
return Support::XPointInRegion(this, (int)point.x, (int)point.y);
|
||||||
// don't even try it against the region's rects.
|
|
||||||
if (!point_in(bound, pt))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (long c = 0; c < count; c++) {
|
|
||||||
if (point_in(data[c], pt))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -249,17 +261,9 @@ BRegion::Contains(BPoint pt) const
|
|||||||
\return \ctrue if the region contains the point, \cfalse if not.
|
\return \ctrue if the region contains the point, \cfalse if not.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
BRegion::Contains(int32 x, int32 y)
|
BRegion::Contains(int32 x, int32 y) /*const*/
|
||||||
{
|
{
|
||||||
// see above
|
return Support::XPointInRegion(this, x, y);
|
||||||
if (!point_in(bound, x, y))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (long c = 0; c < count; c++) {
|
|
||||||
if (point_in(data[c], x, y))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -270,26 +274,34 @@ BRegion::PrintToStream() const
|
|||||||
{
|
{
|
||||||
Frame().PrintToStream();
|
Frame().PrintToStream();
|
||||||
|
|
||||||
for (long c = 0; c < count; c++) {
|
for (long i = 0; i < fCount; i++) {
|
||||||
clipping_rect *rect = &data[c];
|
clipping_rect *rect = &fData[i];
|
||||||
printf("data = BRect(l:%ld.0, t:%ld.0, r:%ld.0, b:%ld.0)\n",
|
printf("data[%ld] = BRect(l:%ld.0, t:%ld.0, r:%ld.0, b:%ld.0)\n",
|
||||||
rect->left, rect->top, rect->right, rect->bottom);
|
i, rect->left, rect->top, rect->right - 1, rect->bottom - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Offsets all region's rects, and bounds by the given values.
|
/*! \brief Offsets all region's rects, and bounds by the given values.
|
||||||
\param dh The horizontal offset.
|
\param dh The horizontal offset.
|
||||||
\param dv The vertical offset.
|
\param dv The vertical offset.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::OffsetBy(int32 dh, int32 dv)
|
BRegion::OffsetBy(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
if (count > 0) {
|
if (x == 0 && y == 0)
|
||||||
for (long c = 0; c < count; c++)
|
return;
|
||||||
offset_rect(data[c], dh, dv);
|
|
||||||
|
|
||||||
offset_rect(bound, dh, dv);
|
if (fCount > 0) {
|
||||||
|
if (fData != &fBounds) {
|
||||||
|
for (long i = 0; i < fCount; i++)
|
||||||
|
offset_rect(fData[i], x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset_rect(fBounds, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,17 +311,21 @@ BRegion::OffsetBy(int32 dh, int32 dv)
|
|||||||
void
|
void
|
||||||
BRegion::MakeEmpty()
|
BRegion::MakeEmpty()
|
||||||
{
|
{
|
||||||
Support::ZeroRegion(*this);
|
fBounds = (clipping_rect){ 0, 0, 0, 0 };
|
||||||
|
fCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Modifies the region, so that it includes the given BRect.
|
/*! \brief Modifies the region, so that it includes the given BRect.
|
||||||
\param rect The BRect to be included by the region.
|
\param rect The BRect to be included by the region.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::Include(BRect rect)
|
BRegion::Include(BRect rect)
|
||||||
{
|
{
|
||||||
Include(to_clipping_rect(rect));
|
Include(_Convert(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -319,13 +335,17 @@ BRegion::Include(BRect rect)
|
|||||||
void
|
void
|
||||||
BRegion::Include(clipping_rect rect)
|
BRegion::Include(clipping_rect rect)
|
||||||
{
|
{
|
||||||
BRegion region;
|
// convert to internal rect format
|
||||||
BRegion newRegion;
|
rect.right ++;
|
||||||
|
rect.bottom ++;
|
||||||
|
|
||||||
region.Set(rect);
|
// use private clipping_rect constructor which avoids malloc()
|
||||||
|
BRegion t(rect);
|
||||||
|
|
||||||
Support::OrRegion(*this, region, newRegion);
|
BRegion result;
|
||||||
Support::CopyRegion(newRegion, *this);
|
Support::XUnionRegion(this, &t, &result);
|
||||||
|
|
||||||
|
_AdoptRegionData(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -335,20 +355,23 @@ BRegion::Include(clipping_rect rect)
|
|||||||
void
|
void
|
||||||
BRegion::Include(const BRegion* region)
|
BRegion::Include(const BRegion* region)
|
||||||
{
|
{
|
||||||
BRegion newRegion;
|
BRegion result;
|
||||||
|
Support::XUnionRegion(this, region, &result);
|
||||||
|
|
||||||
Support::OrRegion(*this, *region, newRegion);
|
_AdoptRegionData(result);
|
||||||
Support::CopyRegion(newRegion, *this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Modifies the region, excluding the area represented by the given BRect.
|
/*! \brief Modifies the region, excluding the area represented by the given BRect.
|
||||||
\param rect The BRect to be excluded.
|
\param rect The BRect to be excluded.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::Exclude(BRect rect)
|
BRegion::Exclude(BRect rect)
|
||||||
{
|
{
|
||||||
Exclude(to_clipping_rect(rect));
|
Exclude(_Convert(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -358,150 +381,146 @@ BRegion::Exclude(BRect rect)
|
|||||||
void
|
void
|
||||||
BRegion::Exclude(clipping_rect rect)
|
BRegion::Exclude(clipping_rect rect)
|
||||||
{
|
{
|
||||||
BRegion region;
|
// convert to internal rect format
|
||||||
BRegion newRegion;
|
rect.right ++;
|
||||||
|
rect.bottom ++;
|
||||||
|
|
||||||
region.Set(rect);
|
// use private clipping_rect constructor which avoids malloc()
|
||||||
|
BRegion t(rect);
|
||||||
|
|
||||||
Support::SubRegion(*this, region, newRegion);
|
BRegion result;
|
||||||
Support::CopyRegion(newRegion, *this);
|
Support::XSubtractRegion(this, &t, &result);
|
||||||
|
|
||||||
|
_AdoptRegionData(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Modifies the region, excluding the area contained in the given BRegion.
|
/*! \brief Modifies the region, excluding the area contained in the given
|
||||||
|
BRegion.
|
||||||
\param region The BRegion to be excluded.
|
\param region The BRegion to be excluded.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::Exclude(const BRegion* region)
|
BRegion::Exclude(const BRegion* region)
|
||||||
{
|
{
|
||||||
BRegion newRegion;
|
BRegion result;
|
||||||
|
Support::XSubtractRegion(this, region, &result);
|
||||||
|
|
||||||
Support::SubRegion(*this, *region, newRegion);
|
_AdoptRegionData(result);
|
||||||
Support::CopyRegion(newRegion, *this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Modifies the region, so that it will contain just the area in common with the given BRegion.
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Modifies the region, so that it will contain just the area
|
||||||
|
in common with the given BRegion.
|
||||||
\param region the BRegion to intersect to.
|
\param region the BRegion to intersect to.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::IntersectWith(const BRegion* region)
|
BRegion::IntersectWith(const BRegion* region)
|
||||||
{
|
{
|
||||||
BRegion newRegion;
|
BRegion result;
|
||||||
|
Support::XIntersectRegion(this, region, &result);
|
||||||
|
|
||||||
Support::AndRegion(*this, *region, newRegion);
|
_AdoptRegionData(result);
|
||||||
Support::CopyRegion(newRegion, *this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Modifies the region to be a copy of the given BRegion.
|
// #pragma mark -
|
||||||
\param region the BRegion to copy.
|
|
||||||
\return This function always returns \c *this.
|
|
||||||
*/
|
|
||||||
BRegion &
|
|
||||||
BRegion::operator=(const BRegion ®ion)
|
|
||||||
{
|
|
||||||
if (®ion != this) {
|
|
||||||
free(data);
|
|
||||||
bound = region.bound;
|
|
||||||
count = region.count;
|
|
||||||
data_size = region.data_size;
|
|
||||||
|
|
||||||
if (data_size <= 0)
|
|
||||||
data_size = 1;
|
|
||||||
|
|
||||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
|
||||||
|
|
||||||
memcpy(data, region.data, count * sizeof(clipping_rect));
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Adds a rect to the region.
|
/*! \brief Takes over the data of a region and marks that region empty.
|
||||||
\param rect The clipping_rect to be added.
|
\param region The region to adopt the data from.
|
||||||
|
|
||||||
Adds the given rect to the region, merging it with another already contained in the region,
|
|
||||||
if possible. Recalculate the region's bounds if needed.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
BRegion::_AddRect(clipping_rect rect)
|
BRegion::_AdoptRegionData(BRegion& region)
|
||||||
{
|
{
|
||||||
ASSERT(count >= 0);
|
fCount = region.fCount;
|
||||||
ASSERT(data_size >= 0);
|
fDataSize = region.fDataSize;
|
||||||
ASSERT(valid_rect(rect));
|
fBounds = region.fBounds;
|
||||||
|
if (fData != &fBounds)
|
||||||
|
free(fData);
|
||||||
|
if (region.fData != ®ion.fBounds)
|
||||||
|
fData = region.fData;
|
||||||
|
else
|
||||||
|
fData = &fBounds;
|
||||||
|
|
||||||
// Should we just reallocate the memory and
|
// NOTE: MakeEmpty() is not called since _AdoptRegionData is only
|
||||||
// copy the rect ?
|
// called with internally allocated regions, so they don't need to
|
||||||
bool addRect = true;
|
// be left in a valid state.
|
||||||
|
region.fData = NULL;
|
||||||
if (count > 0) {
|
// region.MakeEmpty();
|
||||||
// Wait! We could merge the rect with one of the
|
|
||||||
// existing rectangles, if it's adiacent.
|
|
||||||
// We just check it against the last rectangle, since
|
|
||||||
// we are keeping them sorted by their "top" coordinates.
|
|
||||||
long last = count - 1;
|
|
||||||
if (rect.left == data[last].left && rect.right == data[last].right
|
|
||||||
&& rect.top == data[last].bottom + 1) {
|
|
||||||
|
|
||||||
data[last].bottom = rect.bottom;
|
|
||||||
addRect = false;
|
|
||||||
|
|
||||||
} else if (rect.top == data[last].top && rect.bottom == data[last].bottom) {
|
|
||||||
if (rect.left == data[last].right + 1) {
|
|
||||||
|
|
||||||
data[last].right = rect.right;
|
|
||||||
addRect = false;
|
|
||||||
|
|
||||||
} else if (rect.right == data[last].left - 1) {
|
|
||||||
|
|
||||||
data[last].left = rect.left;
|
|
||||||
addRect = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We weren't lucky.... just add the rect as a new one
|
|
||||||
if (addRect) {
|
|
||||||
if (data_size <= count)
|
|
||||||
set_size(count + 16);
|
|
||||||
|
|
||||||
data[count] = rect;
|
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recalculate bounds
|
|
||||||
if (rect.top < bound.top)
|
|
||||||
bound.top = rect.top;
|
|
||||||
|
|
||||||
if (rect.left < bound.left)
|
|
||||||
bound.left = rect.left;
|
|
||||||
|
|
||||||
if (rect.right > bound.right)
|
|
||||||
bound.right = rect.right;
|
|
||||||
|
|
||||||
if (rect.bottom > bound.bottom)
|
|
||||||
bound.bottom = rect.bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Reallocate the memory in the region.
|
/*! \brief Reallocate the memory in the region.
|
||||||
\param new_size The amount of rectangles that the region could contain.
|
\param newSize The amount of rectangles that the region should be
|
||||||
|
able to hold.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
BRegion::set_size(long new_size)
|
BRegion::_SetSize(long newSize)
|
||||||
{
|
{
|
||||||
if (new_size <= 0)
|
// we never shrink the size
|
||||||
new_size = data_size + 16;
|
newSize = max_c(fDataSize, newSize);
|
||||||
|
if (newSize == fDataSize)
|
||||||
|
return true;
|
||||||
|
|
||||||
data = (clipping_rect *)realloc(data, new_size * sizeof(clipping_rect));
|
// align newSize to multiple of kDataBlockSize
|
||||||
|
newSize = ((newSize + kDataBlockSize - 1) / kDataBlockSize) * kDataBlockSize;
|
||||||
|
|
||||||
if (data == NULL)
|
if (newSize > 0) {
|
||||||
debugger("BRegion::set_size realloc error\n");
|
if (fData == &fBounds) {
|
||||||
|
fData = (clipping_rect*)malloc(newSize * sizeof(clipping_rect));
|
||||||
data_size = new_size;
|
fData[0] = fBounds;
|
||||||
|
} else if (fData) {
|
||||||
ASSERT(count <= data_size);
|
clipping_rect* resizedData = (clipping_rect*)realloc(fData,
|
||||||
|
newSize * sizeof(clipping_rect));
|
||||||
|
if (!resizedData) {
|
||||||
|
// failed to resize, but we cannot keep the
|
||||||
|
// previous state of the object
|
||||||
|
free(fData);
|
||||||
|
fData = NULL;
|
||||||
|
} else
|
||||||
|
fData = resizedData;
|
||||||
|
} else
|
||||||
|
fData = (clipping_rect*)malloc(newSize * sizeof(clipping_rect));
|
||||||
|
} else {
|
||||||
|
// just an empty region, but no error
|
||||||
|
MakeEmpty();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fData) {
|
||||||
|
// allocation actually failed
|
||||||
|
fDataSize = 0;
|
||||||
|
MakeEmpty();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fDataSize = newSize;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
clipping_rect
|
||||||
|
BRegion::_Convert(const BRect& rect) const
|
||||||
|
{
|
||||||
|
return (clipping_rect){ (int)floorf(rect.left), (int)floorf(rect.top),
|
||||||
|
(int)ceilf(rect.right), (int)ceilf(rect.bottom) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
clipping_rect
|
||||||
|
BRegion::_ConvertToInternal(const BRect& rect) const
|
||||||
|
{
|
||||||
|
return (clipping_rect){ (int)floorf(rect.left), (int)floorf(rect.top),
|
||||||
|
(int)ceilf(rect.right) + 1, (int)ceilf(rect.bottom) + 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
clipping_rect
|
||||||
|
BRegion::_ConvertToInternal(const clipping_rect& rect) const
|
||||||
|
{
|
||||||
|
return (clipping_rect){ rect.left, rect.top,
|
||||||
|
rect.right + 1, rect.bottom + 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,11 @@
|
|||||||
- \c B_NOT_ALLOWED: Read only node or volume.
|
- \c B_NOT_ALLOWED: Read only node or volume.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
BStatable::~BStatable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief Returns if the current node is a file.
|
/*! \brief Returns if the current node is a file.
|
||||||
\return \c true, if the BNode is properly initialized and is a file,
|
\return \c true, if the BNode is properly initialized and is a file,
|
||||||
\c false otherwise.
|
\c false otherwise.
|
||||||
|
|||||||
Reference in New Issue
Block a user