зеркало из https://github.com/mozilla/pjs.git
This commit is contained in:
Родитель
ca429dbaea
Коммит
579388fc87
|
@ -0,0 +1,280 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsBlockBandData.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameReflow.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
nsBlockBandData::nsBlockBandData()
|
||||
: mSpaceManager(nsnull),
|
||||
mSpace(0, 0),
|
||||
mSpaceManagerX(0),
|
||||
mSpaceManagerY(0)
|
||||
{
|
||||
size = 12;
|
||||
trapezoids = mData;
|
||||
}
|
||||
|
||||
nsBlockBandData::~nsBlockBandData()
|
||||
{
|
||||
NS_IF_RELEASE(mSpaceManager);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockBandData::Init(nsISpaceManager* aSpaceManager,
|
||||
const nsSize& aSpace)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aSpaceManager, "null pointer");
|
||||
if (nsnull == aSpaceManager) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mSpaceManager);
|
||||
mSpaceManager = aSpaceManager;
|
||||
NS_ADDREF(aSpaceManager);
|
||||
aSpaceManager->GetTranslation(mSpaceManagerX, mSpaceManagerY);
|
||||
|
||||
mSpace = aSpace;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the available reflow space for the current y coordinate. The
|
||||
// available space is relative to our coordinate system (0,0) is our
|
||||
// upper left corner.
|
||||
void
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
|
||||
{
|
||||
// Get the raw band data for the given Y coordinate
|
||||
mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
|
||||
// Compute the bounding rect of the available space, i.e. space
|
||||
// between any left and right floaters.
|
||||
ComputeAvailSpaceRect();
|
||||
|
||||
// Fixup width
|
||||
if (NS_UNCONSTRAINEDSIZE == mSpace.width) {
|
||||
mAvailSpace.width = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
aResult = mAvailSpace;
|
||||
}
|
||||
|
||||
// Get the available reflow space for the current y coordinate. The
|
||||
// available space is relative to our coordinate system (0,0) is our
|
||||
// upper left corner.
|
||||
void
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY)
|
||||
{
|
||||
// Get the raw band data for the given Y coordinate
|
||||
mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
|
||||
// Compute the bounding rect of the available space, i.e. space
|
||||
// between any left and right floaters.
|
||||
ComputeAvailSpaceRect();
|
||||
|
||||
// Fixup width
|
||||
if (NS_UNCONSTRAINEDSIZE == mSpace.width) {
|
||||
mAvailSpace.width = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the bounding rect of the available space, i.e. space
|
||||
* between any left and right floaters. Uses the current trapezoid
|
||||
* data, see nsISpaceManager::GetBandData(). Also updates member
|
||||
* data "availSpace".
|
||||
*/
|
||||
void
|
||||
nsBlockBandData::ComputeAvailSpaceRect()
|
||||
{
|
||||
nsBandTrapezoid* trapezoid = mData;
|
||||
|
||||
if (count > 1) {
|
||||
// If there's more than one trapezoid that means there are floaters
|
||||
PRInt32 i;
|
||||
|
||||
// Stop when we get to space occupied by a right floater, or when we've
|
||||
// looked at every trapezoid and none are right floaters
|
||||
for (i = 0; i < count; i++) {
|
||||
trapezoid = &mData[i];
|
||||
if (trapezoid->state != nsBandTrapezoid::Available) {
|
||||
const nsStyleDisplay* display;
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->state) {
|
||||
PRInt32 j, numFrames = trapezoid->frames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (j = 0; j < numFrames; j++) {
|
||||
nsIFrame* f = (nsIFrame*)trapezoid->frames->ElementAt(j);
|
||||
f->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
goto foundRightFloater;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trapezoid->frame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foundRightFloater:
|
||||
|
||||
if (i > 0) {
|
||||
trapezoid = &mData[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (nsBandTrapezoid::Available == trapezoid->state) {
|
||||
// The trapezoid is available
|
||||
trapezoid->GetRect(mAvailSpace);
|
||||
} else {
|
||||
const nsStyleDisplay* display;
|
||||
|
||||
// The trapezoid is occupied. That means there's no available space
|
||||
trapezoid->GetRect(mAvailSpace);
|
||||
|
||||
// XXX Better handle the case of multiple frames
|
||||
if (nsBandTrapezoid::Occupied == trapezoid->state) {
|
||||
trapezoid->frame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
|
||||
mAvailSpace.x = mAvailSpace.XMost();
|
||||
}
|
||||
}
|
||||
mAvailSpace.width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the given frame should be cleared
|
||||
*/
|
||||
PRBool
|
||||
nsBlockBandData::ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
const nsStyleDisplay* display;
|
||||
nsresult rv = aFrame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull != display)) {
|
||||
if (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
|
||||
if (NS_STYLE_CLEAR_LEFT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
if (NS_STYLE_CLEAR_RIGHT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the frames YMost, in the space managers "root" coordinate
|
||||
* system. Because the floating frame may have been placed in a
|
||||
* parent/child frame, we map the coordinates into the space-managers
|
||||
* untranslated coordinate system.
|
||||
*/
|
||||
nscoord
|
||||
nsBlockBandData::GetFrameYMost(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* spaceFrame;
|
||||
spaceFrame = mSpaceManager->GetFrame();
|
||||
|
||||
nsRect r;
|
||||
nsPoint p;
|
||||
aFrame->GetRect(r);
|
||||
nscoord y = r.y;
|
||||
nsIFrame* parent;
|
||||
aFrame->GetGeometricParent(parent);
|
||||
PRBool done = PR_FALSE;
|
||||
while (!done && (parent != spaceFrame)) {
|
||||
// If parent has a prev-in-flow, check there for equality first
|
||||
// before looking upward.
|
||||
nsIFrame* parentPrevInFlow;
|
||||
parent->GetPrevInFlow(parentPrevInFlow);
|
||||
while (nsnull != parentPrevInFlow) {
|
||||
if (parentPrevInFlow == spaceFrame) {
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
parentPrevInFlow->GetPrevInFlow(parentPrevInFlow);
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
parent->GetOrigin(p);
|
||||
y += p.y;
|
||||
parent->GetGeometricParent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
return y + r.height;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
|
||||
{
|
||||
// Update band information based on target Y before clearing.
|
||||
nscoord oldY = aY;
|
||||
GetAvailableSpace(aY);
|
||||
|
||||
// Compute aY in space-manager "root" coordinates.
|
||||
nscoord finalY = oldY;
|
||||
nscoord aYS = aY + mSpaceManagerY;
|
||||
|
||||
// Calculate the largest trapezoid YMost for the appropriate
|
||||
// floaters in this band.
|
||||
nscoord yMost = aYS;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
nsBandTrapezoid* trapezoid = &mData[i];
|
||||
if (nsBandTrapezoid::Available != trapezoid->state) {
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->state) {
|
||||
PRInt32 fn, numFrames = trapezoid->frames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (fn = 0; fn < numFrames; fn++) {
|
||||
nsIFrame* frame = (nsIFrame*) trapezoid->frames->ElementAt(fn);
|
||||
if (ShouldClearFrame(frame, aBreakType)) {
|
||||
nscoord ym = GetFrameYMost(frame);
|
||||
if (ym > yMost) yMost = ym;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ShouldClearFrame(trapezoid->frame, aBreakType)) {
|
||||
nscoord ym = GetFrameYMost(trapezoid->frame);
|
||||
if (ym > yMost) yMost = ym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If yMost is unchanged (aYS) then there were no appropriate
|
||||
// floaters in the band. In that case we restore mY to its
|
||||
// original value.
|
||||
if (yMost != aYS) {
|
||||
finalY = aY + (yMost - aYS);
|
||||
}
|
||||
|
||||
return finalY;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#ifndef nsBlockBandData_h___
|
||||
#define nsBlockBandData_h___
|
||||
|
||||
#include "nsISpaceManager.h"
|
||||
|
||||
/**
|
||||
* Class used to manage processing of the space-manager band data.
|
||||
* Provides HTML/CSS specific behavior to the raw data.
|
||||
*/
|
||||
class nsBlockBandData : public nsBandData {
|
||||
public:
|
||||
nsBlockBandData();
|
||||
~nsBlockBandData();
|
||||
|
||||
// Initialize. This must be called before any of the other methods.
|
||||
nsresult Init(nsISpaceManager* aSpaceManager, const nsSize& aSpace);
|
||||
|
||||
// Get some available space. Note that aY is relative to the current
|
||||
// space manager translation.
|
||||
void GetAvailableSpace(nscoord aY, nsRect& aResult);
|
||||
|
||||
// Clear any current floaters, returning a new Y coordinate
|
||||
nscoord ClearFloaters(nscoord aY, PRUint8 aBreakType);
|
||||
|
||||
nscoord GetTrapezoidCount() const {
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The spacemanager we are getting space from
|
||||
nsISpaceManager* mSpaceManager;
|
||||
nscoord mSpaceManagerX, mSpaceManagerY;
|
||||
|
||||
// Limit to the available space (set by Init)
|
||||
nsSize mSpace;
|
||||
|
||||
// Trapezoids used during band processing
|
||||
// nsBlockBandData what happens if we need more than 12 trapezoids?
|
||||
nsBandTrapezoid mData[12];
|
||||
|
||||
// Bounding rect of available space between any left and right floaters
|
||||
nsRect mAvailSpace;
|
||||
|
||||
void ComputeAvailSpaceRect();
|
||||
void GetAvailableSpace(nscoord aY);
|
||||
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
|
||||
nscoord GetFrameYMost(nsIFrame* aFrame);
|
||||
};
|
||||
|
||||
#endif /* nsBlockBandData_h___ */
|
|
@ -0,0 +1,280 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsBlockBandData.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameReflow.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
nsBlockBandData::nsBlockBandData()
|
||||
: mSpaceManager(nsnull),
|
||||
mSpace(0, 0),
|
||||
mSpaceManagerX(0),
|
||||
mSpaceManagerY(0)
|
||||
{
|
||||
size = 12;
|
||||
trapezoids = mData;
|
||||
}
|
||||
|
||||
nsBlockBandData::~nsBlockBandData()
|
||||
{
|
||||
NS_IF_RELEASE(mSpaceManager);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBlockBandData::Init(nsISpaceManager* aSpaceManager,
|
||||
const nsSize& aSpace)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aSpaceManager, "null pointer");
|
||||
if (nsnull == aSpaceManager) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mSpaceManager);
|
||||
mSpaceManager = aSpaceManager;
|
||||
NS_ADDREF(aSpaceManager);
|
||||
aSpaceManager->GetTranslation(mSpaceManagerX, mSpaceManagerY);
|
||||
|
||||
mSpace = aSpace;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the available reflow space for the current y coordinate. The
|
||||
// available space is relative to our coordinate system (0,0) is our
|
||||
// upper left corner.
|
||||
void
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
|
||||
{
|
||||
// Get the raw band data for the given Y coordinate
|
||||
mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
|
||||
// Compute the bounding rect of the available space, i.e. space
|
||||
// between any left and right floaters.
|
||||
ComputeAvailSpaceRect();
|
||||
|
||||
// Fixup width
|
||||
if (NS_UNCONSTRAINEDSIZE == mSpace.width) {
|
||||
mAvailSpace.width = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
aResult = mAvailSpace;
|
||||
}
|
||||
|
||||
// Get the available reflow space for the current y coordinate. The
|
||||
// available space is relative to our coordinate system (0,0) is our
|
||||
// upper left corner.
|
||||
void
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY)
|
||||
{
|
||||
// Get the raw band data for the given Y coordinate
|
||||
mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
|
||||
// Compute the bounding rect of the available space, i.e. space
|
||||
// between any left and right floaters.
|
||||
ComputeAvailSpaceRect();
|
||||
|
||||
// Fixup width
|
||||
if (NS_UNCONSTRAINEDSIZE == mSpace.width) {
|
||||
mAvailSpace.width = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the bounding rect of the available space, i.e. space
|
||||
* between any left and right floaters. Uses the current trapezoid
|
||||
* data, see nsISpaceManager::GetBandData(). Also updates member
|
||||
* data "availSpace".
|
||||
*/
|
||||
void
|
||||
nsBlockBandData::ComputeAvailSpaceRect()
|
||||
{
|
||||
nsBandTrapezoid* trapezoid = mData;
|
||||
|
||||
if (count > 1) {
|
||||
// If there's more than one trapezoid that means there are floaters
|
||||
PRInt32 i;
|
||||
|
||||
// Stop when we get to space occupied by a right floater, or when we've
|
||||
// looked at every trapezoid and none are right floaters
|
||||
for (i = 0; i < count; i++) {
|
||||
trapezoid = &mData[i];
|
||||
if (trapezoid->state != nsBandTrapezoid::Available) {
|
||||
const nsStyleDisplay* display;
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->state) {
|
||||
PRInt32 j, numFrames = trapezoid->frames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (j = 0; j < numFrames; j++) {
|
||||
nsIFrame* f = (nsIFrame*)trapezoid->frames->ElementAt(j);
|
||||
f->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
goto foundRightFloater;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trapezoid->frame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foundRightFloater:
|
||||
|
||||
if (i > 0) {
|
||||
trapezoid = &mData[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (nsBandTrapezoid::Available == trapezoid->state) {
|
||||
// The trapezoid is available
|
||||
trapezoid->GetRect(mAvailSpace);
|
||||
} else {
|
||||
const nsStyleDisplay* display;
|
||||
|
||||
// The trapezoid is occupied. That means there's no available space
|
||||
trapezoid->GetRect(mAvailSpace);
|
||||
|
||||
// XXX Better handle the case of multiple frames
|
||||
if (nsBandTrapezoid::Occupied == trapezoid->state) {
|
||||
trapezoid->frame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
|
||||
mAvailSpace.x = mAvailSpace.XMost();
|
||||
}
|
||||
}
|
||||
mAvailSpace.width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the given frame should be cleared
|
||||
*/
|
||||
PRBool
|
||||
nsBlockBandData::ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
const nsStyleDisplay* display;
|
||||
nsresult rv = aFrame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&)display);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull != display)) {
|
||||
if (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
else if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
|
||||
if (NS_STYLE_CLEAR_LEFT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
|
||||
if (NS_STYLE_CLEAR_RIGHT == aBreakType) {
|
||||
result = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the frames YMost, in the space managers "root" coordinate
|
||||
* system. Because the floating frame may have been placed in a
|
||||
* parent/child frame, we map the coordinates into the space-managers
|
||||
* untranslated coordinate system.
|
||||
*/
|
||||
nscoord
|
||||
nsBlockBandData::GetFrameYMost(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* spaceFrame;
|
||||
spaceFrame = mSpaceManager->GetFrame();
|
||||
|
||||
nsRect r;
|
||||
nsPoint p;
|
||||
aFrame->GetRect(r);
|
||||
nscoord y = r.y;
|
||||
nsIFrame* parent;
|
||||
aFrame->GetGeometricParent(parent);
|
||||
PRBool done = PR_FALSE;
|
||||
while (!done && (parent != spaceFrame)) {
|
||||
// If parent has a prev-in-flow, check there for equality first
|
||||
// before looking upward.
|
||||
nsIFrame* parentPrevInFlow;
|
||||
parent->GetPrevInFlow(parentPrevInFlow);
|
||||
while (nsnull != parentPrevInFlow) {
|
||||
if (parentPrevInFlow == spaceFrame) {
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
parentPrevInFlow->GetPrevInFlow(parentPrevInFlow);
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
parent->GetOrigin(p);
|
||||
y += p.y;
|
||||
parent->GetGeometricParent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
return y + r.height;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
|
||||
{
|
||||
// Update band information based on target Y before clearing.
|
||||
nscoord oldY = aY;
|
||||
GetAvailableSpace(aY);
|
||||
|
||||
// Compute aY in space-manager "root" coordinates.
|
||||
nscoord finalY = oldY;
|
||||
nscoord aYS = aY + mSpaceManagerY;
|
||||
|
||||
// Calculate the largest trapezoid YMost for the appropriate
|
||||
// floaters in this band.
|
||||
nscoord yMost = aYS;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
nsBandTrapezoid* trapezoid = &mData[i];
|
||||
if (nsBandTrapezoid::Available != trapezoid->state) {
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->state) {
|
||||
PRInt32 fn, numFrames = trapezoid->frames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (fn = 0; fn < numFrames; fn++) {
|
||||
nsIFrame* frame = (nsIFrame*) trapezoid->frames->ElementAt(fn);
|
||||
if (ShouldClearFrame(frame, aBreakType)) {
|
||||
nscoord ym = GetFrameYMost(frame);
|
||||
if (ym > yMost) yMost = ym;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ShouldClearFrame(trapezoid->frame, aBreakType)) {
|
||||
nscoord ym = GetFrameYMost(trapezoid->frame);
|
||||
if (ym > yMost) yMost = ym;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If yMost is unchanged (aYS) then there were no appropriate
|
||||
// floaters in the band. In that case we restore mY to its
|
||||
// original value.
|
||||
if (yMost != aYS) {
|
||||
finalY = aY + (yMost - aYS);
|
||||
}
|
||||
|
||||
return finalY;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#ifndef nsBlockBandData_h___
|
||||
#define nsBlockBandData_h___
|
||||
|
||||
#include "nsISpaceManager.h"
|
||||
|
||||
/**
|
||||
* Class used to manage processing of the space-manager band data.
|
||||
* Provides HTML/CSS specific behavior to the raw data.
|
||||
*/
|
||||
class nsBlockBandData : public nsBandData {
|
||||
public:
|
||||
nsBlockBandData();
|
||||
~nsBlockBandData();
|
||||
|
||||
// Initialize. This must be called before any of the other methods.
|
||||
nsresult Init(nsISpaceManager* aSpaceManager, const nsSize& aSpace);
|
||||
|
||||
// Get some available space. Note that aY is relative to the current
|
||||
// space manager translation.
|
||||
void GetAvailableSpace(nscoord aY, nsRect& aResult);
|
||||
|
||||
// Clear any current floaters, returning a new Y coordinate
|
||||
nscoord ClearFloaters(nscoord aY, PRUint8 aBreakType);
|
||||
|
||||
nscoord GetTrapezoidCount() const {
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The spacemanager we are getting space from
|
||||
nsISpaceManager* mSpaceManager;
|
||||
nscoord mSpaceManagerX, mSpaceManagerY;
|
||||
|
||||
// Limit to the available space (set by Init)
|
||||
nsSize mSpace;
|
||||
|
||||
// Trapezoids used during band processing
|
||||
// nsBlockBandData what happens if we need more than 12 trapezoids?
|
||||
nsBandTrapezoid mData[12];
|
||||
|
||||
// Bounding rect of available space between any left and right floaters
|
||||
nsRect mAvailSpace;
|
||||
|
||||
void ComputeAvailSpaceRect();
|
||||
void GetAvailableSpace(nscoord aY);
|
||||
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
|
||||
nscoord GetFrameYMost(nsIFrame* aFrame);
|
||||
};
|
||||
|
||||
#endif /* nsBlockBandData_h___ */
|
Загрузка…
Ссылка в новой задаче