Changed nsISpaceManager interface to conform to XP-COM conventions on

return values
This commit is contained in:
troy%netscape.com 1999-01-04 04:54:33 +00:00
Родитель b392c2d9e9
Коммит 76dc813a2c
10 изменённых файлов: 495 добавлений и 263 удалений

Просмотреть файл

@ -53,7 +53,7 @@ struct nsBandTrapezoid {
};
// Get the height of the trapezoid
nscoord GetHeight() {return yBottom - yTop;}
nscoord GetHeight() const {return yBottom - yTop;}
// Get the bouding rect of the trapezoid
void GetRect(nsRect& aRect) const;
@ -67,9 +67,9 @@ struct nsBandTrapezoid {
* @see #GetBandData()
*/
struct nsBandData {
PRInt32 count; // 'out' parameter. Actual number of trapezoids in the band data
PRInt32 size; // 'in' parameter. The size of the array
nsBandTrapezoid* trapezoids; // 'out' parameter. Array of length 'size'
PRInt32 count; // [out] actual number of trapezoids in the band data
PRInt32 size; // [in] the size of the array (number of trapezoids)
nsBandTrapezoid* trapezoids; // [out] array of length 'size'
};
/**
@ -84,27 +84,26 @@ public:
* Get the frame that's associated with the space manager. This frame created
* the space manager, and the world coordinate space is relative to this frame.
*
* You can use QueryInterface() on this frame to get additional interfaces such
* as nsIAnchoredItems
* You can use QueryInterface() on this frame to get any additional interfaces
*/
virtual nsIFrame* GetFrame() const = 0;
NS_IMETHOD GetFrame(nsIFrame*& aFrame) const = 0;
/**
* Translate the current origin by the specified (dx, dy). This creates a new
* local coordinate space relative to the current coordinate space.
*/
virtual void Translate(nscoord aDx, nscoord aDy) = 0;
NS_IMETHOD Translate(nscoord aDx, nscoord aDy) = 0;
/**
* Returns the current translation from local coordinate space to world
* coordinate space. This represents the accumulated calls to Translate().
*/
virtual void GetTranslation(nscoord& aX, nscoord& aY) const = 0;
NS_IMETHOD GetTranslation(nscoord& aX, nscoord& aY) const = 0;
/**
* Returns the y-most of the bottommost band, or 0 if there are no bands.
*/
virtual nscoord YMost() const = 0;
NS_IMETHOD YMost(nscoord& aYMost) const = 0;
/**
* Returns a band starting at the specified y-offset. The band data indicates
@ -113,20 +112,20 @@ public:
* The band data that is returned is in the coordinate space of the local
* coordinate system.
*
* The local coordinate space origin together with the max size describe a
* rectangle that's used to clip the underlying band of available space.
* The local coordinate space origin, the y-offset, and the max size describe
* a rectangle that's used to clip the underlying band of available space, i.e.
* {0, aYOffset, aMaxSize.width, aMaxSize.height} in the local coordinate space
*
* @param aYOffset the y-offset of where the band begins. The coordinate is
* relative to the upper-left corner of the local coordinate space
* @param aMaxSize the size to use to constrain the band data
* @param aBandData <i>out</i> parameter used to return the list of
* trapezoids that describe the available space and the unavailable
* space.
* @returns the number of trapezoids in the band data. If the band data is
* not large enough, returns the negative of the number of
* trapezoids needed
* @param aBandData [in,out] used to return the list of trapezoids that
* describe the available space and the unavailable space
* @return NS_OK if successful and NS_ERROR_FAILURE if the band data is not
* not large enough. The 'count' member of the band data struct
* indicates how large the array of trapezoids needs to be
*/
virtual PRInt32 GetBandData(nscoord aYOffset,
NS_IMETHOD GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const = 0;
@ -134,28 +133,31 @@ public:
* Add a rectangular region of unavailable space. The space is relative to
* the local coordinate system.
*
* The region is tagged with a frame, which is used to identify the region.
* The frame must not be NULL
* The region is tagged with a frame. When translated to world coordinates
* the origin of the rect MUST be within the defined coordinate space, i.e.
* the x-offset and y-offset must be >= 0
*
* Returns PR_TRUE if successful and PR_FALSE otherwise, e.g. there is already
* a region tagged with aFrame
*
* When translated to world coordinates the origin MUST be within the defined
* coordinate space, i.e. the x-offset and y-offset must be >= 0
* @param aFrame the frame used to identify the region. Must not be NULL
* @param aUnavailableSpace the bounding rect of the unavailable space
* @return NS_OK if successful
* NS_ERROR_FAILURE if there is already a region tagged with aFrame
* NS_ERROR_INVALID_ARG if the rect translated to world coordinates
* is not within the defined coordinate space
*/
virtual PRBool AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace) = 0;
NS_IMETHOD AddRectRegion(nsIFrame* aFrame,
const nsRect& aUnavailableSpace) = 0;
/**
* Resize the rectangular region associated with aFrame by the specified deltas.
* The height change always applies to the bottom edge or the existing rect.
* You specify whether the width change applies to the left or right edge
* Resize the rectangular region associated with aFrame by the specified
* deltas. The height change always applies to the bottom edge or the existing
* rect. You specify whether the width change applies to the left or right edge
*
* Returns PR_TRUE if successful and PR_FALSE otherwise, e.g. there is no region
* tagged with aFrame, or the new offset when translated to world coordinates is
* outside the defined coordinate space
* Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
* tagged with aFrame, and NS_ERROR_FAILURE if the new offset when translated
* to world coordinates is outside the defined coordinate space
*/
enum AffectedEdge {LeftEdge, RightEdge};
virtual PRBool ResizeRectRegion(nsIFrame* aFrame,
NS_IMETHOD ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge = RightEdge) = 0;
@ -163,24 +165,24 @@ public:
/**
* Offset the region associated with aFrame by the specified amount.
*
* Returns PR_TRUE if successful and PR_FALSE otherwise, e.g. there is no region
* tagged with aFrame, or the new offset when translated to world coordinates
* is outside the defined coordinate space
* Returns NS_OK if successful, NS_ERROR_INVALID_ARG if there is no region
* tagged with aFrame, and NS_ERROR_FAILURE if the new offset when translated
* to world coordinates is outside the defined coordinate space
*/
virtual PRBool OffsetRegion(nsIFrame* aFrame, nscoord dx, nscoord dy) = 0;
NS_IMETHOD OffsetRegion(nsIFrame* aFrame, nscoord dx, nscoord dy) = 0;
/**
* Remove the region associated with aFrane.
*
* Returns PR_TRUE if successful and PR_FALSE otherwise, e.g. there is no region
* Returns NS_OK if successful and NS_ERROR_INVALID_ARG if there is no region
* tagged with aFrame
*/
virtual PRBool RemoveRegion(nsIFrame* aFrame) = 0;
NS_IMETHOD RemoveRegion(nsIFrame* aFrame) = 0;
/**
* Clears the list of regions representing the unavailable space.
*/
virtual void ClearRegions() = 0;
NS_IMETHOD ClearRegions() = 0;
};
void inline nsBandTrapezoid::GetRect(nsRect& aRect) const

Просмотреть файл

@ -50,7 +50,8 @@ nsSpaceManager::BandList::BandList()
numFrames = 0;
}
void nsSpaceManager::BandList::Clear()
void
nsSpaceManager::BandList::Clear()
{
if (!IsEmpty()) {
BandRect* bandRect = Head();
@ -66,7 +67,6 @@ void nsSpaceManager::BandList::Clear()
}
}
/////////////////////////////////////////////////////////////////////////////
// nsSpaceManager
@ -78,7 +78,8 @@ nsSpaceManager::nsSpaceManager(nsIFrame* aFrame)
mFrameInfoMap = nsnull;
}
void nsSpaceManager::ClearFrameInfo()
void
nsSpaceManager::ClearFrameInfo()
{
if (nsnull != mFrameInfoMap) {
PL_HashTableEnumerateEntries(mFrameInfoMap, NS_RemoveFrameInfoEntries, 0);
@ -95,36 +96,41 @@ nsSpaceManager::~nsSpaceManager()
NS_IMPL_ISUPPORTS(nsSpaceManager, kISpaceManagerIID);
nsIFrame* nsSpaceManager::GetFrame() const
NS_IMETHODIMP
nsSpaceManager::GetFrame(nsIFrame*& aFrame) const
{
return mFrame;
aFrame = mFrame;
return NS_OK;
}
void nsSpaceManager::Translate(nscoord aDx, nscoord aDy)
NS_IMETHODIMP
nsSpaceManager::Translate(nscoord aDx, nscoord aDy)
{
mX += aDx;
mY += aDy;
return NS_OK;
}
void nsSpaceManager::GetTranslation(nscoord& aX, nscoord& aY) const
NS_IMETHODIMP
nsSpaceManager::GetTranslation(nscoord& aX, nscoord& aY) const
{
aX = mX;
aY = mY;
return NS_OK;
}
nscoord nsSpaceManager::YMost() const
NS_IMETHODIMP
nsSpaceManager::YMost(nscoord& aYMost) const
{
nscoord yMost;
if (mBandList.IsEmpty()) {
yMost = 0;
aYMost = 0;
} else {
BandRect* lastRect = mBandList.Tail();
yMost = lastRect->bottom;
aYMost = lastRect->bottom;
}
return yMost;
return NS_OK;
}
/**
@ -136,7 +142,8 @@ nscoord nsSpaceManager::YMost() const
* @param aMaxSize the size to use to constrain the band data
* @param aAvailableBand
*/
PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
nsresult
nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
nscoord aY,
const nsSize& aMaxSize,
nsBandData& aBandData) const
@ -171,6 +178,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
if (aBand->left > left) {
// The rect is to the right of our current left coordinate, so we've
// found some available space
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count += 2 * aBand->Length() + 2; // estimate the number needed
return NS_ERROR_FAILURE;
}
trapezoid->state = nsBandTrapezoid::Available;
trapezoid->frame = nsnull;
@ -184,6 +196,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
}
// The rect represents unavailable space, so add another trapezoid
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count += 2 * aBand->Length() + 1; // estimate the number needed
return NS_ERROR_FAILURE;
}
if (1 == aBand->numFrames) {
trapezoid->state = nsBandTrapezoid::Occupied;
trapezoid->frame = aBand->frame;
@ -218,6 +235,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
// No more rects left in the band. If we haven't yet reached the right edge,
// then all the remaining space is available
if (left < rightEdge) {
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count++;
return NS_ERROR_FAILURE;
}
trapezoid->state = nsBandTrapezoid::Available;
trapezoid->frame = nsnull;
@ -227,19 +249,25 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
aBandData.count++;
}
return aBandData.count;
return NS_OK;
}
PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
NS_IMETHODIMP
nsSpaceManager::GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const
{
NS_PRECONDITION(aBandData.size >= 1, "bad band data");
nsresult result = NS_OK;
// Convert the y-offset to world coordinates
nscoord y = mY + aYOffset;
// If there are no unavailable rects or the offset is below the bottommost
// band, then all the space is available
if (y >= YMost()) {
nscoord yMost;
YMost(yMost);
if (y >= yMost) {
// All the requested space is available
aBandData.count = 1;
aBandData.trapezoids[0] = nsRect(0, aYOffset, aMaxSize.width, aMaxSize.height);
@ -273,7 +301,7 @@ PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
}
NS_POSTCONDITION(aBandData.count > 0, "unexpected band data count");
return aBandData.count;
return result;
}
/**
@ -282,7 +310,8 @@ PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
* @param aBandRect A rect within the band
* @returns The start of the next band, or nsnull of this is the last band.
*/
nsSpaceManager::BandRect* nsSpaceManager::GetNextBand(const BandRect* aBandRect) const
nsSpaceManager::BandRect*
nsSpaceManager::GetNextBand(const BandRect* aBandRect) const
{
nscoord topOfBand = aBandRect->top;
@ -308,7 +337,8 @@ nsSpaceManager::BandRect* nsSpaceManager::GetNextBand(const BandRect* aBandRect)
* @param aBottom where to split the band. This becomes the bottom of the top
* part
*/
void nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
void
nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
{
NS_PRECONDITION(aBottom < aBandRect->bottom, "bad height");
nscoord topOfBand = aBandRect->top;
@ -330,7 +360,8 @@ void nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
}
}
PRBool nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
PRBool
nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
{
PRBool result;
nscoord topOfBand = aBand->top;
@ -384,7 +415,8 @@ PRBool nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
*
* If the two bands are joined, the previous band is the the band that's deleted
*/
PRBool nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
PRBool
nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
{
if (CanJoinBands(aBand, aPrevBand)) {
BandRect* startOfNextBand = aBand;
@ -415,8 +447,8 @@ PRBool nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
* @param aBand the first rect in the band
* @param aBandRect the band rect to add to the band
*/
void nsSpaceManager::AddRectToBand(BandRect* aBand,
BandRect* aBandRect)
void
nsSpaceManager::AddRectToBand(BandRect* aBand, BandRect* aBandRect)
{
NS_PRECONDITION((aBand->top == aBandRect->top) &&
(aBand->bottom == aBandRect->bottom), "bad band");
@ -580,11 +612,14 @@ void nsSpaceManager::AddRectToBand(BandRect* aBand,
// | R |
// +-----+
//
void nsSpaceManager::InsertBandRect(BandRect* aBandRect)
void
nsSpaceManager::InsertBandRect(BandRect* aBandRect)
{
// If there are no existing bands or this rect is below the bottommost
// band, then add a new band
if (aBandRect->top >= YMost()) {
nscoord yMost;
YMost(yMost);
if (aBandRect->top >= yMost) {
mBandList.Append(aBandRect);
return;
}
@ -673,7 +708,8 @@ void nsSpaceManager::InsertBandRect(BandRect* aBandRect)
}
}
PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace)
NS_IMETHODIMP
nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace)
{
NS_PRECONDITION(nsnull != aFrame, "null frame");
@ -682,7 +718,7 @@ PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailabl
if (nsnull != frameInfo) {
NS_WARNING("aFrame is already associated with a region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// Convert the frame to world coordinates
@ -692,27 +728,34 @@ PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailabl
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset for rect region");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Create a frame info structure
frameInfo = CreateFrameInfo(aFrame, rect);
if (nsnull == frameInfo) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Is the rect empty?
if (aUnavailableSpace.IsEmpty()) {
// The rect doesn't consume any space, so don't add any band data
return PR_TRUE;
return NS_OK;
}
// Allocate a band rect
BandRect* bandRect = new BandRect(rect.x, rect.y, rect.XMost(), rect.YMost(), aFrame);
if (nsnull == bandRect) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Insert the band rect
InsertBandRect(bandRect);
return PR_TRUE;
return NS_OK;
}
PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
NS_IMETHODIMP
nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge)
@ -722,9 +765,10 @@ PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Compute new rect
nsRect rect(frameInfo->rect);
rect.SizeBy(aDeltaWidth, aDeltaHeight);
if (aEdge == LeftEdge) {
@ -734,51 +778,55 @@ PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset when resizing rect region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// For the time being just remove it and add it back in
// For the time being just remove it and add it back in. Because
// AddRectRegion() operates relative to the local coordinate space,
// translate from world coordinates to the local coordinate space
rect.MoveBy(-mX, -mY);
RemoveRegion(aFrame);
return AddRectRegion(aFrame, rect);
}
PRBool nsSpaceManager::OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy)
NS_IMETHODIMP
nsSpaceManager::OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy)
{
// Get the frame info associated with with aFrame
FrameInfo* frameInfo = GetFrameInfoFor(aFrame);
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Compute new rect for the region; note that we have to translate
// from the global coordinate system (frameInfo->rect) to our
// current local coordinate system before adding the rect region
// again (since AddRectRegion operates relative to the current
// translation).
// Compute new rect
nsRect rect(frameInfo->rect);
rect.MoveBy(-mX + aDx, -mY + aDy);
rect.MoveBy(aDx, aDy);
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset when offseting rect region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// For the time being just remove it and add it back in
// For the time being just remove it and add it back in. Because
// AddRectRegion() operates relative to the local coordinate space,
// translate from world coordinates to the local coordinate space
rect.MoveBy(-mX, -mY);
RemoveRegion(aFrame);
return AddRectRegion(aFrame, rect);
}
PRBool nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
NS_IMETHODIMP
nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
{
// Get the frame info associated with aFrame
FrameInfo* frameInfo = GetFrameInfoFor(aFrame);
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
if (!frameInfo->rect.IsEmpty()) {
@ -871,16 +919,19 @@ PRBool nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
}
DestroyFrameInfo(frameInfo);
return PR_TRUE;
return NS_OK;
}
void nsSpaceManager::ClearRegions()
NS_IMETHODIMP
nsSpaceManager::ClearRegions()
{
ClearFrameInfo();
mBandList.Clear();
return NS_OK;
}
nsSpaceManager::FrameInfo* nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
nsSpaceManager::FrameInfo*
nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
{
FrameInfo* result = nsnull;
@ -891,21 +942,26 @@ nsSpaceManager::FrameInfo* nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
return result;
}
nsSpaceManager::FrameInfo* nsSpaceManager::CreateFrameInfo(nsIFrame* aFrame,
const nsRect& aRect)
nsSpaceManager::FrameInfo*
nsSpaceManager::CreateFrameInfo(nsIFrame* aFrame, const nsRect& aRect)
{
if (nsnull == mFrameInfoMap) {
mFrameInfoMap = PL_NewHashTable(17, NS_HashNumber, PL_CompareValues,
PL_CompareValues, nsnull, nsnull);
if (nsnull == mFrameInfoMap) {
return nsnull;
}
}
FrameInfo* frameInfo = new FrameInfo(aFrame, aRect);
if (nsnull != frameInfo) {
PL_HashTableAdd(mFrameInfoMap, (const void*)aFrame, frameInfo);
}
return frameInfo;
}
void nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
void
nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
{
PL_HashTableRemove(mFrameInfoMap, (const void*)aFrameInfo->frame);
delete aFrameInfo;
@ -958,7 +1014,8 @@ nsSpaceManager::BandRect::~BandRect()
}
}
nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitVertically(nscoord aBottom)
nsSpaceManager::BandRect*
nsSpaceManager::BandRect::SplitVertically(nscoord aBottom)
{
NS_PRECONDITION((aBottom > top) && (aBottom < bottom), "bad argument");
@ -973,11 +1030,11 @@ nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitVertically(nscoord aBot
// This band rect becomes the top part, so adjust the bottom edge
bottom = aBottom;
return bottomBandRect;
}
nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitHorizontally(nscoord aRight)
nsSpaceManager::BandRect*
nsSpaceManager::BandRect::SplitHorizontally(nscoord aRight)
{
NS_PRECONDITION((aRight > left) && (aRight < right), "bad argument");
@ -992,11 +1049,11 @@ nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitHorizontally(nscoord aR
// This band rect becomes the left part, so adjust the right edge
right = aRight;
return rightBandRect;
}
PRBool nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
PRBool
nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
{
PRBool result;
@ -1019,7 +1076,8 @@ PRBool nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
return result;
}
void nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
void
nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
{
if (1 == numFrames) {
nsIFrame* f = frame;
@ -1032,7 +1090,8 @@ void nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
NS_POSTCONDITION(frames->Count() == numFrames, "bad frame count");
}
void nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
void
nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
{
NS_PRECONDITION(numFrames > 1, "only one frame");
frames->RemoveElement((void*)aFrame);
@ -1046,7 +1105,8 @@ void nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
}
}
PRBool nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) const
PRBool
nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) const
{
PRBool result;
@ -1073,3 +1133,26 @@ PRBool nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) con
return result;
}
/**
* Internal helper function that counts the number of rects in this band
* including the current band rect
*/
PRInt32
nsSpaceManager::BandRect::Length() const
{
nscoord topOfBand = top;
PRInt32 len = 1;
BandRect* bandRect = Next();
// Because there's a header cell we know we'll either find the next band
// (which has a different y-offset) or the header cell which has an invalid
// y-offset
while (bandRect->top == top) {
len++;
bandRect = bandRect->Next();
}
return len;
}

Просмотреть файл

@ -35,25 +35,26 @@ public:
NS_DECL_ISUPPORTS
// nsISpaceManager
virtual nsIFrame* GetFrame() const;
NS_IMETHOD GetFrame(nsIFrame*& aFrame) const;
virtual void Translate(nscoord aDx, nscoord aDy);
virtual void GetTranslation(nscoord& aX, nscoord& aY) const;
virtual nscoord YMost() const;
NS_IMETHOD Translate(nscoord aDx, nscoord aDy);
NS_IMETHOD GetTranslation(nscoord& aX, nscoord& aY) const;
NS_IMETHOD YMost(nscoord& aYMost) const;
virtual PRInt32 GetBandData(nscoord aYOffset,
NS_IMETHOD GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const;
virtual PRBool AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace);
virtual PRBool ResizeRectRegion(nsIFrame* aFrame,
NS_IMETHOD AddRectRegion(nsIFrame* aFrame,
const nsRect& aUnavailableSpace);
NS_IMETHOD ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge);
virtual PRBool OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy);
virtual PRBool RemoveRegion(nsIFrame* aFrame);
NS_IMETHOD OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy);
NS_IMETHOD RemoveRegion(nsIFrame* aFrame);
virtual void ClearRegions();
NS_IMETHOD ClearRegions();
protected:
// Structure that maintains information about the region associated
@ -109,6 +110,7 @@ protected:
void AddFrame(const nsIFrame*);
void RemoveFrame(const nsIFrame*);
PRBool HasSameFrameList(const BandRect* aBandRect) const;
PRInt32 Length() const;
};
// Circular linked list of band rects
@ -147,7 +149,7 @@ protected:
void AddRectToBand(BandRect* aBand, BandRect* aBandRect);
void InsertBandRect(BandRect* aBandRect);
PRInt32 GetBandAvailableSpace(const BandRect* aBand,
nsresult GetBandAvailableSpace(const BandRect* aBand,
nscoord aY,
const nsSize& aMaxSize,
nsBandData& aAvailableSpace) const;

Просмотреть файл

@ -31,6 +31,7 @@ public:
PRBool TestRemoveRegion();
PRBool TestOffsetRegion();
PRBool TestResizeRectRegion();
PRBool TestGetBandData();
protected:
struct BandInfo {
@ -92,8 +93,8 @@ void MySpaceManager::GetBandsInfo(BandsInfo& aBandsInfo)
// 4. adding a new band below the bottommost band
PRBool MySpaceManager::TestAddBand()
{
PRBool status;
BandsInfo bandsInfo;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -103,8 +104,8 @@ PRBool MySpaceManager::TestAddBand()
// #1. Add a rect region. Verify the return status, and that a band rect is
// added
status = AddRectRegion((nsIFrame*)0x01, nsRect(10, 100, 100, 100));
if (PR_FALSE == status) {
printf("TestAddBand: add returned false (#1)\n");
if (NS_FAILED(status)) {
printf("TestAddBand: add failed (#1)\n");
return PR_FALSE;
}
GetBandsInfo(bandsInfo);
@ -120,7 +121,7 @@ PRBool MySpaceManager::TestAddBand()
/////////////////////////////////////////////////////////////////////////////
// #2. Add another band rect completely above the first band rect
status = AddRectRegion((nsIFrame*)0x02, nsRect(10, 10, 100, 20));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 2) {
printf("TestAddBand: wrong number of bands (#2): %i\n", bandsInfo.numBands);
@ -135,7 +136,7 @@ PRBool MySpaceManager::TestAddBand()
/////////////////////////////////////////////////////////////////////////////
// #3. Now insert a new band between the two existing bands
status = AddRectRegion((nsIFrame*)0x03, nsRect(10, 40, 100, 30));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 3) {
printf("TestAddBand: wrong number of bands (#3): %i\n", bandsInfo.numBands);
@ -151,7 +152,7 @@ PRBool MySpaceManager::TestAddBand()
/////////////////////////////////////////////////////////////////////////////
// #4. Append a new bottommost band
status = AddRectRegion((nsIFrame*)0x04, nsRect(10, 210, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 4) {
printf("TestAddBand: wrong number of bands (#4): %i\n", bandsInfo.numBands);
@ -177,8 +178,8 @@ PRBool MySpaceManager::TestAddBand()
// 3. Adding a rect that contains an existing band
PRBool MySpaceManager::TestAddBandOverlap()
{
PRBool status;
BandsInfo bandsInfo;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -186,12 +187,12 @@ PRBool MySpaceManager::TestAddBandOverlap()
// Add a new band
status = AddRectRegion((nsIFrame*)0x01, nsRect(100, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
/////////////////////////////////////////////////////////////////////////////
// #1. Add a rect region that's above and partially overlaps an existing band
status = AddRectRegion((nsIFrame*)0x02, nsRect(10, 50, 50, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 3) {
printf("TestAddBandOverlap: wrong number of bands (#1): %i\n", bandsInfo.numBands);
@ -213,7 +214,7 @@ PRBool MySpaceManager::TestAddBandOverlap()
/////////////////////////////////////////////////////////////////////////////
// #2. Add a rect region that's contained by the first band
status = AddRectRegion((nsIFrame*)0x03, nsRect(200, 60, 50, 10));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 5) {
printf("TestAddBandOverlap: wrong number of bands (#2): %i\n", bandsInfo.numBands);
@ -239,7 +240,7 @@ PRBool MySpaceManager::TestAddBandOverlap()
/////////////////////////////////////////////////////////////////////////////
// #3. Add a rect that overlaps and is below an existing band
status = AddRectRegion((nsIFrame*)0x04, nsRect(200, 175, 50, 50));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 7) {
printf("TestAddBandOverlap: wrong number of bands (#3): %i\n", bandsInfo.numBands);
@ -270,11 +271,11 @@ PRBool MySpaceManager::TestAddBandOverlap()
// #4. Now test adding a rect that contains an existing band
ClearRegions();
status = AddRectRegion((nsIFrame*)0x01, nsRect(100, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Now add a rect that contains the existing band vertically
status = AddRectRegion((nsIFrame*)0x02, nsRect(200, 50, 100, 200));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 3) {
@ -308,9 +309,9 @@ PRBool MySpaceManager::TestAddBandOverlap()
// 6. Add a new rect that completely contains an existing rect
PRBool MySpaceManager::TestAddRectToBand()
{
PRBool status;
BandsInfo bandsInfo;
BandRect* bandRect;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -318,12 +319,12 @@ PRBool MySpaceManager::TestAddRectToBand()
// Add a new band
status = AddRectRegion((nsIFrame*)0x01, nsRect(100, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
/////////////////////////////////////////////////////////////////////////////
// #1. Add a rect region that's to the left of the existing rect
status = AddRectRegion((nsIFrame*)0x02, nsRect(10, 100, 50, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 1) {
printf("TestAddRectToBand: wrong number of bands (#1): %i\n", bandsInfo.numBands);
@ -347,7 +348,7 @@ PRBool MySpaceManager::TestAddRectToBand()
/////////////////////////////////////////////////////////////////////////////
// #2. Add a rect region that's to the right of the rightmost rect
status = AddRectRegion((nsIFrame*)0x03, nsRect(250, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
NS_ASSERTION(bandsInfo.numBands == 1, "wrong number of bands");
if (bandsInfo.bands[0].numRects != 3) {
@ -374,7 +375,7 @@ PRBool MySpaceManager::TestAddRectToBand()
// #3. Add a rect region that's to the left of an existing rect and that
// overlaps the rect
status = AddRectRegion((nsIFrame*)0x04, nsRect(80, 100, 40, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
NS_ASSERTION(bandsInfo.numBands == 1, "wrong number of bands");
if (bandsInfo.bands[0].numRects != 5) {
@ -414,7 +415,7 @@ PRBool MySpaceManager::TestAddRectToBand()
// #4. Add a rect region that's to the right of an existing rect and that
// overlaps the rect
status = AddRectRegion((nsIFrame*)0x05, nsRect(50, 100, 20, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
NS_ASSERTION(bandsInfo.numBands == 1, "wrong number of bands");
if (bandsInfo.bands[0].numRects != 7) {
@ -450,7 +451,7 @@ PRBool MySpaceManager::TestAddRectToBand()
// #5. Add a new rect over top of an existing rect (existing rect contains
// the new rect)
status = AddRectRegion((nsIFrame*)0x06, nsRect(20, 100, 20, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
NS_ASSERTION(bandsInfo.numBands == 1, "wrong number of bands");
if (bandsInfo.bands[0].numRects != 9) {
@ -484,7 +485,7 @@ PRBool MySpaceManager::TestAddRectToBand()
/////////////////////////////////////////////////////////////////////////////
// #6. Add a new rect that completely contains an existing rect
status = AddRectRegion((nsIFrame*)0x07, nsRect(0, 100, 30, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
NS_ASSERTION(bandsInfo.numBands == 1, "wrong number of bands");
if (bandsInfo.bands[0].numRects != 11) {
@ -533,9 +534,9 @@ PRBool MySpaceManager::TestAddRectToBand()
// 3. removing a band rect and making sure adjacent bands are combined
PRBool MySpaceManager::TestRemoveRegion()
{
PRBool status;
BandsInfo bandsInfo;
BandRect* bandRect;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -544,9 +545,9 @@ PRBool MySpaceManager::TestRemoveRegion()
/////////////////////////////////////////////////////////////////////////////
// #1. A simple test of removing the one and only band rect
status = AddRectRegion((nsIFrame*)0x01, nsRect(10, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = RemoveRegion((nsIFrame*)0x01);
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.numBands != 0) {
printf("TestRemoveRegion: wrong number of bands (#1): %i\n", bandsInfo.numBands);
@ -557,9 +558,9 @@ PRBool MySpaceManager::TestRemoveRegion()
// #2. Test removing a rect that's shared. Make sure adjacent rects are
// coalesced
status = AddRectRegion((nsIFrame*)0x01, nsRect(10, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = AddRectRegion((nsIFrame*)0x02, nsRect(40, 100, 20, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Verify there are three rects in the band
GetBandsInfo(bandsInfo);
@ -570,7 +571,7 @@ PRBool MySpaceManager::TestRemoveRegion()
// Remove the region associated with the second frame
status = RemoveRegion((nsIFrame*)0x02);
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.bands[0].numRects != 1) {
printf("TestRemoveRegion: failed to coalesce adjacent rects (#2)\n");
@ -585,7 +586,7 @@ PRBool MySpaceManager::TestRemoveRegion()
/////////////////////////////////////////////////////////////////////////////
// #3. Test removing a band rect and making sure adjacent bands are combined
status = AddRectRegion((nsIFrame*)0x02, nsRect(10, 140, 20, 20));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Verify there are three bands and that each band has three rects
GetBandsInfo(bandsInfo);
@ -608,7 +609,7 @@ PRBool MySpaceManager::TestRemoveRegion()
// Remove the region associated with the second frame
status = RemoveRegion((nsIFrame*)0x02);
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
GetBandsInfo(bandsInfo);
if (bandsInfo.bands[0].numRects != 1) {
printf("TestRemoveRegion: failed to coalesce adjacent rects (#3)\n");
@ -629,9 +630,9 @@ PRBool MySpaceManager::TestRemoveRegion()
// 1. simple test of offseting the one and only band rect
PRBool MySpaceManager::TestOffsetRegion()
{
PRBool status;
BandsInfo bandsInfo;
BandRect* bandRect;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -640,9 +641,9 @@ PRBool MySpaceManager::TestOffsetRegion()
/////////////////////////////////////////////////////////////////////////////
// #1. A simple test of offseting the one and only band rect
status = AddRectRegion((nsIFrame*)0x01, nsRect(10, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = OffsetRegion((nsIFrame*)0x01, 50, 50);
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Verify there is one band with one rect
GetBandsInfo(bandsInfo);
@ -671,9 +672,9 @@ PRBool MySpaceManager::TestOffsetRegion()
// 1. simple test of resizing the one and only band rect
PRBool MySpaceManager::TestResizeRectRegion()
{
PRBool status;
BandsInfo bandsInfo;
BandRect* bandRect;
nsresult status;
// Clear any existing regions
ClearRegions();
@ -682,9 +683,9 @@ PRBool MySpaceManager::TestResizeRectRegion()
/////////////////////////////////////////////////////////////////////////////
// #1. A simple test of resizing the right edge of the one and only band rect
status = AddRectRegion((nsIFrame*)0x01, nsRect(10, 100, 100, 100));
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = ResizeRectRegion((nsIFrame*)0x01, 50, 50, nsISpaceManager::RightEdge);
NS_ASSERTION(PR_TRUE == status, "unexpected status");
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Verify there is one band with one rect
GetBandsInfo(bandsInfo);
@ -708,6 +709,63 @@ PRBool MySpaceManager::TestResizeRectRegion()
return PR_TRUE;
}
// Test of getting the band data
PRBool MySpaceManager::TestGetBandData()
{
BandsInfo bandsInfo;
BandRect* bandRect;
nsresult status;
// Clear any existing regions
ClearRegions();
NS_ASSERTION(mBandList.IsEmpty(), "clear regions failed");
// Make a band with three rects
status = AddRectRegion((nsIFrame*)0x01, nsRect(100, 100, 100, 100));
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = AddRectRegion((nsIFrame*)0x02, nsRect(300, 100, 100, 100));
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
status = AddRectRegion((nsIFrame*)0x03, nsRect(500, 100, 100, 100));
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Get the band data using a very large clip rect and a band data struct
// that's large enough
nsBandData bandData;
nsBandTrapezoid trapezoids[16];
bandData.size = 16;
bandData.trapezoids = trapezoids;
status = GetBandData(100, nsSize(10000,10000), bandData);
NS_ASSERTION(NS_SUCCEEDED(status), "unexpected status");
// Verify that there are seven trapezoids
if (bandData.count != 7) {
printf("TestGetBandData: wrong trapezoid count (#1)\n");
return PR_FALSE;
}
// Get the band data using a very large clip rect and a band data struct
// that's too small
bandData.size = 3;
status = GetBandData(100, nsSize(10000,10000), bandData);
if (NS_SUCCEEDED(status)) {
printf("TestGetBandData: ignored band data count (#2)\n");
return PR_FALSE;
}
// Make sure the count has been updated to reflect the number of trapezoids
// required
if (bandData.count <= bandData.size) {
printf("TestGetBandData: bad band data count (#2)\n");
return PR_FALSE;
}
// XXX We need lots more tests here...
return PR_TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//
@ -751,11 +809,11 @@ int main(int argc, char** argv)
return -1;
}
#if 0
// Test getting the band data
if (!spaceMgr->TestGetBandData()) {
return -1;
}
#endif
NS_RELEASE(spaceMgr);
return 0;
}

Просмотреть файл

@ -295,7 +295,8 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
// Compute our desired size. Take into account any floaters when computing the
// height
nscoord floaterYMost = mSpaceManager->YMost();
nscoord floaterYMost;
mSpaceManager->YMost(floaterYMost);
if (floaterYMost > 0) {
// What we need to check for is if the bottom most floater extends below
// the content area of the desired size

Просмотреть файл

@ -230,7 +230,7 @@ nscoord
nsBlockBandData::GetFrameYMost(nsIFrame* aFrame)
{
nsIFrame* spaceFrame;
spaceFrame = mSpaceManager->GetFrame();
mSpaceManager->GetFrame(spaceFrame);
nsRect r;
nsPoint p;

Просмотреть файл

@ -50,7 +50,8 @@ nsSpaceManager::BandList::BandList()
numFrames = 0;
}
void nsSpaceManager::BandList::Clear()
void
nsSpaceManager::BandList::Clear()
{
if (!IsEmpty()) {
BandRect* bandRect = Head();
@ -66,7 +67,6 @@ void nsSpaceManager::BandList::Clear()
}
}
/////////////////////////////////////////////////////////////////////////////
// nsSpaceManager
@ -78,7 +78,8 @@ nsSpaceManager::nsSpaceManager(nsIFrame* aFrame)
mFrameInfoMap = nsnull;
}
void nsSpaceManager::ClearFrameInfo()
void
nsSpaceManager::ClearFrameInfo()
{
if (nsnull != mFrameInfoMap) {
PL_HashTableEnumerateEntries(mFrameInfoMap, NS_RemoveFrameInfoEntries, 0);
@ -95,36 +96,41 @@ nsSpaceManager::~nsSpaceManager()
NS_IMPL_ISUPPORTS(nsSpaceManager, kISpaceManagerIID);
nsIFrame* nsSpaceManager::GetFrame() const
NS_IMETHODIMP
nsSpaceManager::GetFrame(nsIFrame*& aFrame) const
{
return mFrame;
aFrame = mFrame;
return NS_OK;
}
void nsSpaceManager::Translate(nscoord aDx, nscoord aDy)
NS_IMETHODIMP
nsSpaceManager::Translate(nscoord aDx, nscoord aDy)
{
mX += aDx;
mY += aDy;
return NS_OK;
}
void nsSpaceManager::GetTranslation(nscoord& aX, nscoord& aY) const
NS_IMETHODIMP
nsSpaceManager::GetTranslation(nscoord& aX, nscoord& aY) const
{
aX = mX;
aY = mY;
return NS_OK;
}
nscoord nsSpaceManager::YMost() const
NS_IMETHODIMP
nsSpaceManager::YMost(nscoord& aYMost) const
{
nscoord yMost;
if (mBandList.IsEmpty()) {
yMost = 0;
aYMost = 0;
} else {
BandRect* lastRect = mBandList.Tail();
yMost = lastRect->bottom;
aYMost = lastRect->bottom;
}
return yMost;
return NS_OK;
}
/**
@ -136,7 +142,8 @@ nscoord nsSpaceManager::YMost() const
* @param aMaxSize the size to use to constrain the band data
* @param aAvailableBand
*/
PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
nsresult
nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
nscoord aY,
const nsSize& aMaxSize,
nsBandData& aBandData) const
@ -171,6 +178,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
if (aBand->left > left) {
// The rect is to the right of our current left coordinate, so we've
// found some available space
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count += 2 * aBand->Length() + 2; // estimate the number needed
return NS_ERROR_FAILURE;
}
trapezoid->state = nsBandTrapezoid::Available;
trapezoid->frame = nsnull;
@ -184,6 +196,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
}
// The rect represents unavailable space, so add another trapezoid
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count += 2 * aBand->Length() + 1; // estimate the number needed
return NS_ERROR_FAILURE;
}
if (1 == aBand->numFrames) {
trapezoid->state = nsBandTrapezoid::Occupied;
trapezoid->frame = aBand->frame;
@ -218,6 +235,11 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
// No more rects left in the band. If we haven't yet reached the right edge,
// then all the remaining space is available
if (left < rightEdge) {
if (aBandData.count >= aBandData.size) {
// Not enough space in the array of trapezoids
aBandData.count++;
return NS_ERROR_FAILURE;
}
trapezoid->state = nsBandTrapezoid::Available;
trapezoid->frame = nsnull;
@ -227,19 +249,25 @@ PRInt32 nsSpaceManager::GetBandAvailableSpace(const BandRect* aBand,
aBandData.count++;
}
return aBandData.count;
return NS_OK;
}
PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
NS_IMETHODIMP
nsSpaceManager::GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const
{
NS_PRECONDITION(aBandData.size >= 1, "bad band data");
nsresult result = NS_OK;
// Convert the y-offset to world coordinates
nscoord y = mY + aYOffset;
// If there are no unavailable rects or the offset is below the bottommost
// band, then all the space is available
if (y >= YMost()) {
nscoord yMost;
YMost(yMost);
if (y >= yMost) {
// All the requested space is available
aBandData.count = 1;
aBandData.trapezoids[0] = nsRect(0, aYOffset, aMaxSize.width, aMaxSize.height);
@ -273,7 +301,7 @@ PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
}
NS_POSTCONDITION(aBandData.count > 0, "unexpected band data count");
return aBandData.count;
return result;
}
/**
@ -282,7 +310,8 @@ PRInt32 nsSpaceManager::GetBandData(nscoord aYOffset,
* @param aBandRect A rect within the band
* @returns The start of the next band, or nsnull of this is the last band.
*/
nsSpaceManager::BandRect* nsSpaceManager::GetNextBand(const BandRect* aBandRect) const
nsSpaceManager::BandRect*
nsSpaceManager::GetNextBand(const BandRect* aBandRect) const
{
nscoord topOfBand = aBandRect->top;
@ -308,7 +337,8 @@ nsSpaceManager::BandRect* nsSpaceManager::GetNextBand(const BandRect* aBandRect)
* @param aBottom where to split the band. This becomes the bottom of the top
* part
*/
void nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
void
nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
{
NS_PRECONDITION(aBottom < aBandRect->bottom, "bad height");
nscoord topOfBand = aBandRect->top;
@ -330,7 +360,8 @@ void nsSpaceManager::DivideBand(BandRect* aBandRect, nscoord aBottom)
}
}
PRBool nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
PRBool
nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
{
PRBool result;
nscoord topOfBand = aBand->top;
@ -384,7 +415,8 @@ PRBool nsSpaceManager::CanJoinBands(BandRect* aBand, BandRect* aPrevBand)
*
* If the two bands are joined, the previous band is the the band that's deleted
*/
PRBool nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
PRBool
nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
{
if (CanJoinBands(aBand, aPrevBand)) {
BandRect* startOfNextBand = aBand;
@ -415,8 +447,8 @@ PRBool nsSpaceManager::JoinBands(BandRect* aBand, BandRect* aPrevBand)
* @param aBand the first rect in the band
* @param aBandRect the band rect to add to the band
*/
void nsSpaceManager::AddRectToBand(BandRect* aBand,
BandRect* aBandRect)
void
nsSpaceManager::AddRectToBand(BandRect* aBand, BandRect* aBandRect)
{
NS_PRECONDITION((aBand->top == aBandRect->top) &&
(aBand->bottom == aBandRect->bottom), "bad band");
@ -580,11 +612,14 @@ void nsSpaceManager::AddRectToBand(BandRect* aBand,
// | R |
// +-----+
//
void nsSpaceManager::InsertBandRect(BandRect* aBandRect)
void
nsSpaceManager::InsertBandRect(BandRect* aBandRect)
{
// If there are no existing bands or this rect is below the bottommost
// band, then add a new band
if (aBandRect->top >= YMost()) {
nscoord yMost;
YMost(yMost);
if (aBandRect->top >= yMost) {
mBandList.Append(aBandRect);
return;
}
@ -673,7 +708,8 @@ void nsSpaceManager::InsertBandRect(BandRect* aBandRect)
}
}
PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace)
NS_IMETHODIMP
nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace)
{
NS_PRECONDITION(nsnull != aFrame, "null frame");
@ -682,7 +718,7 @@ PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailabl
if (nsnull != frameInfo) {
NS_WARNING("aFrame is already associated with a region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// Convert the frame to world coordinates
@ -692,27 +728,34 @@ PRBool nsSpaceManager::AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailabl
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset for rect region");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Create a frame info structure
frameInfo = CreateFrameInfo(aFrame, rect);
if (nsnull == frameInfo) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Is the rect empty?
if (aUnavailableSpace.IsEmpty()) {
// The rect doesn't consume any space, so don't add any band data
return PR_TRUE;
return NS_OK;
}
// Allocate a band rect
BandRect* bandRect = new BandRect(rect.x, rect.y, rect.XMost(), rect.YMost(), aFrame);
if (nsnull == bandRect) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Insert the band rect
InsertBandRect(bandRect);
return PR_TRUE;
return NS_OK;
}
PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
NS_IMETHODIMP
nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge)
@ -722,9 +765,10 @@ PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Compute new rect
nsRect rect(frameInfo->rect);
rect.SizeBy(aDeltaWidth, aDeltaHeight);
if (aEdge == LeftEdge) {
@ -734,51 +778,55 @@ PRBool nsSpaceManager::ResizeRectRegion(nsIFrame* aFrame,
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset when resizing rect region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// For the time being just remove it and add it back in
// For the time being just remove it and add it back in. Because
// AddRectRegion() operates relative to the local coordinate space,
// translate from world coordinates to the local coordinate space
rect.MoveBy(-mX, -mY);
RemoveRegion(aFrame);
return AddRectRegion(aFrame, rect);
}
PRBool nsSpaceManager::OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy)
NS_IMETHODIMP
nsSpaceManager::OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy)
{
// Get the frame info associated with with aFrame
FrameInfo* frameInfo = GetFrameInfoFor(aFrame);
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
// Compute new rect for the region; note that we have to translate
// from the global coordinate system (frameInfo->rect) to our
// current local coordinate system before adding the rect region
// again (since AddRectRegion operates relative to the current
// translation).
// Compute new rect
nsRect rect(frameInfo->rect);
rect.MoveBy(-mX + aDx, -mY + aDy);
rect.MoveBy(aDx, aDy);
// Verify that the offset is within the defined coordinate space
if ((rect.x < 0) || (rect.y < 0)) {
NS_WARNING("invalid offset when offseting rect region");
return PR_FALSE;
return NS_ERROR_FAILURE;
}
// For the time being just remove it and add it back in
// For the time being just remove it and add it back in. Because
// AddRectRegion() operates relative to the local coordinate space,
// translate from world coordinates to the local coordinate space
rect.MoveBy(-mX, -mY);
RemoveRegion(aFrame);
return AddRectRegion(aFrame, rect);
}
PRBool nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
NS_IMETHODIMP
nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
{
// Get the frame info associated with aFrame
FrameInfo* frameInfo = GetFrameInfoFor(aFrame);
if (nsnull == frameInfo) {
NS_WARNING("no region associated with aFrame");
return PR_FALSE;
return NS_ERROR_INVALID_ARG;
}
if (!frameInfo->rect.IsEmpty()) {
@ -871,16 +919,19 @@ PRBool nsSpaceManager::RemoveRegion(nsIFrame* aFrame)
}
DestroyFrameInfo(frameInfo);
return PR_TRUE;
return NS_OK;
}
void nsSpaceManager::ClearRegions()
NS_IMETHODIMP
nsSpaceManager::ClearRegions()
{
ClearFrameInfo();
mBandList.Clear();
return NS_OK;
}
nsSpaceManager::FrameInfo* nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
nsSpaceManager::FrameInfo*
nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
{
FrameInfo* result = nsnull;
@ -891,21 +942,26 @@ nsSpaceManager::FrameInfo* nsSpaceManager::GetFrameInfoFor(nsIFrame* aFrame)
return result;
}
nsSpaceManager::FrameInfo* nsSpaceManager::CreateFrameInfo(nsIFrame* aFrame,
const nsRect& aRect)
nsSpaceManager::FrameInfo*
nsSpaceManager::CreateFrameInfo(nsIFrame* aFrame, const nsRect& aRect)
{
if (nsnull == mFrameInfoMap) {
mFrameInfoMap = PL_NewHashTable(17, NS_HashNumber, PL_CompareValues,
PL_CompareValues, nsnull, nsnull);
if (nsnull == mFrameInfoMap) {
return nsnull;
}
}
FrameInfo* frameInfo = new FrameInfo(aFrame, aRect);
if (nsnull != frameInfo) {
PL_HashTableAdd(mFrameInfoMap, (const void*)aFrame, frameInfo);
}
return frameInfo;
}
void nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
void
nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
{
PL_HashTableRemove(mFrameInfoMap, (const void*)aFrameInfo->frame);
delete aFrameInfo;
@ -958,7 +1014,8 @@ nsSpaceManager::BandRect::~BandRect()
}
}
nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitVertically(nscoord aBottom)
nsSpaceManager::BandRect*
nsSpaceManager::BandRect::SplitVertically(nscoord aBottom)
{
NS_PRECONDITION((aBottom > top) && (aBottom < bottom), "bad argument");
@ -973,11 +1030,11 @@ nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitVertically(nscoord aBot
// This band rect becomes the top part, so adjust the bottom edge
bottom = aBottom;
return bottomBandRect;
}
nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitHorizontally(nscoord aRight)
nsSpaceManager::BandRect*
nsSpaceManager::BandRect::SplitHorizontally(nscoord aRight)
{
NS_PRECONDITION((aRight > left) && (aRight < right), "bad argument");
@ -992,11 +1049,11 @@ nsSpaceManager::BandRect* nsSpaceManager::BandRect::SplitHorizontally(nscoord aR
// This band rect becomes the left part, so adjust the right edge
right = aRight;
return rightBandRect;
}
PRBool nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
PRBool
nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
{
PRBool result;
@ -1019,7 +1076,8 @@ PRBool nsSpaceManager::BandRect::IsOccupiedBy(const nsIFrame* aFrame) const
return result;
}
void nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
void
nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
{
if (1 == numFrames) {
nsIFrame* f = frame;
@ -1032,7 +1090,8 @@ void nsSpaceManager::BandRect::AddFrame(const nsIFrame* aFrame)
NS_POSTCONDITION(frames->Count() == numFrames, "bad frame count");
}
void nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
void
nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
{
NS_PRECONDITION(numFrames > 1, "only one frame");
frames->RemoveElement((void*)aFrame);
@ -1046,7 +1105,8 @@ void nsSpaceManager::BandRect::RemoveFrame(const nsIFrame* aFrame)
}
}
PRBool nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) const
PRBool
nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) const
{
PRBool result;
@ -1073,3 +1133,26 @@ PRBool nsSpaceManager::BandRect::HasSameFrameList(const BandRect* aBandRect) con
return result;
}
/**
* Internal helper function that counts the number of rects in this band
* including the current band rect
*/
PRInt32
nsSpaceManager::BandRect::Length() const
{
nscoord topOfBand = top;
PRInt32 len = 1;
BandRect* bandRect = Next();
// Because there's a header cell we know we'll either find the next band
// (which has a different y-offset) or the header cell which has an invalid
// y-offset
while (bandRect->top == top) {
len++;
bandRect = bandRect->Next();
}
return len;
}

Просмотреть файл

@ -35,25 +35,26 @@ public:
NS_DECL_ISUPPORTS
// nsISpaceManager
virtual nsIFrame* GetFrame() const;
NS_IMETHOD GetFrame(nsIFrame*& aFrame) const;
virtual void Translate(nscoord aDx, nscoord aDy);
virtual void GetTranslation(nscoord& aX, nscoord& aY) const;
virtual nscoord YMost() const;
NS_IMETHOD Translate(nscoord aDx, nscoord aDy);
NS_IMETHOD GetTranslation(nscoord& aX, nscoord& aY) const;
NS_IMETHOD YMost(nscoord& aYMost) const;
virtual PRInt32 GetBandData(nscoord aYOffset,
NS_IMETHOD GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const;
virtual PRBool AddRectRegion(nsIFrame* aFrame, const nsRect& aUnavailableSpace);
virtual PRBool ResizeRectRegion(nsIFrame* aFrame,
NS_IMETHOD AddRectRegion(nsIFrame* aFrame,
const nsRect& aUnavailableSpace);
NS_IMETHOD ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge);
virtual PRBool OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy);
virtual PRBool RemoveRegion(nsIFrame* aFrame);
NS_IMETHOD OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy);
NS_IMETHOD RemoveRegion(nsIFrame* aFrame);
virtual void ClearRegions();
NS_IMETHOD ClearRegions();
protected:
// Structure that maintains information about the region associated
@ -109,6 +110,7 @@ protected:
void AddFrame(const nsIFrame*);
void RemoveFrame(const nsIFrame*);
PRBool HasSameFrameList(const BandRect* aBandRect) const;
PRInt32 Length() const;
};
// Circular linked list of band rects
@ -147,7 +149,7 @@ protected:
void AddRectToBand(BandRect* aBand, BandRect* aBandRect);
void InsertBandRect(BandRect* aBandRect);
PRInt32 GetBandAvailableSpace(const BandRect* aBand,
nsresult GetBandAvailableSpace(const BandRect* aBand,
nscoord aY,
const nsSize& aMaxSize,
nsBandData& aAvailableSpace) const;

Просмотреть файл

@ -295,7 +295,8 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
// Compute our desired size. Take into account any floaters when computing the
// height
nscoord floaterYMost = mSpaceManager->YMost();
nscoord floaterYMost;
mSpaceManager->YMost(floaterYMost);
if (floaterYMost > 0) {
// What we need to check for is if the bottom most floater extends below
// the content area of the desired size

Просмотреть файл

@ -230,7 +230,7 @@ nscoord
nsBlockBandData::GetFrameYMost(nsIFrame* aFrame)
{
nsIFrame* spaceFrame;
spaceFrame = mSpaceManager->GetFrame();
mSpaceManager->GetFrame(spaceFrame);
nsRect r;
nsPoint p;