Treat relatively positioned elements at original position for flowing around floats. b=205087 r+sr=bzbarsky

git-svn-id: svn://10.0.0.236/trunk@151166 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dbaron%dbaron.org
2004-01-11 04:29:09 +00:00
parent 5f39126ffe
commit 3d49352c78
6 changed files with 114 additions and 30 deletions

View File

@@ -131,6 +131,7 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
// Alphabetical list of frame property names
LAYOUT_ATOM(changeListProperty, "ChangeListProperty") // void*
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
LAYOUT_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*

View File

@@ -131,6 +131,7 @@ LAYOUT_ATOM(viewportFrame, "ViewportFrame")
// Alphabetical list of frame property names
LAYOUT_ATOM(changeListProperty, "ChangeListProperty") // void*
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
LAYOUT_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
LAYOUT_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
LAYOUT_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*

View File

@@ -41,6 +41,7 @@
#include "nsSpaceManager.h"
#include "nsIFontMetrics.h"
#include "nsIPresContext.h"
#include "nsIFrameManager.h"
#include "nsIContent.h"
#include "nsStyleContext.h"
#include "nsHTMLReflowCommand.h"
@@ -291,6 +292,14 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, nsMa
}
}
static void
nsPointDtor(nsIPresContext *aPresContext, nsIFrame *aFrame,
nsIAtom *aPropertyName, void *aPropertyValue)
{
nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue);
delete point;
}
nsresult
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
PRBool aApplyTopMargin,
@@ -373,6 +382,23 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
aComputedOffsets = aFrameRS.mComputedOffsets;
if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
nsIFrameManager *frameManager = mPresContext->GetFrameManager();
nsPoint *offsets;
frameManager->GetFrameProperty(mFrame,
nsLayoutAtoms::computedOffsetProperty, 0,
(void**)&offsets);
if (offsets)
offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top);
else {
offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top);
if (offsets)
frameManager->SetFrameProperty(mFrame,
nsLayoutAtoms::computedOffsetProperty,
offsets, nsPointDtor);
}
}
aFrameRS.mLineLayout = nsnull;
if (!aIsAdjacentWithTop) {
aFrameRS.mFlags.mIsTopOfPage = PR_FALSE; // make sure this is cleared
@@ -452,6 +478,16 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
}
// Compute the translation to be used for adjusting the spacemanagager
// coordinate system for the frame. The spacemanager coordinates are
// <b>inside</b> the callers border+padding, but the x/y coordinates
// are not (recall that frame coordinates are relative to the parents
// origin and that the parents border/padding is <b>inside</b> the
// parent frame. Therefore we have to subtract out the parents
// border+padding before translating.
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
// If the element is relatively positioned, then adjust x and y accordingly
if (NS_STYLE_POSITION_RELATIVE == aFrameRS.mStyleDisplay->mPosition) {
x += aFrameRS.mComputedOffsets.left;
@@ -477,15 +513,6 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
#endif
// Adjust spacemanager coordinate system for the frame. The
// spacemanager coordinates are <b>inside</b> the callers
// border+padding, but the x/y coordinates are not (recall that
// frame coordinates are relative to the parents origin and that the
// parents border/padding is <b>inside</b> the parent
// frame. Therefore we have to subtract out the parents
// border+padding before translating.
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
mOuterReflowState.mSpaceManager->Translate(tx, ty);
// See if this is the child's initial reflow and we are supposed to

View File

@@ -484,9 +484,25 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
} else if (aLine->IsBlock()) {
nsBlockFrame *kid = nsnull;
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
if (kid) {
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
mSpaceManager->Translate(kidx, kidy);
// don't recover any state inside a block that has its own space
// manager (we don't currently have any blocks like this, though,
// thanks to our use of extra frames for 'overflow')
if (kid && !(kid->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
nscoord tx = kid->mRect.x, ty = kid->mRect.y;
// If the element is relatively positioned, then adjust x and y
// accordingly so that we consider relatively positioned frames
// at their original position.
if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) {
nsPoint *offsets;
if (NS_OK == mPresContext->GetFrameManager()->GetFrameProperty(kid,
nsLayoutAtoms::computedOffsetProperty, 0, (void**)&offsets)) {
tx -= offsets->x;
ty -= offsets->y;
}
}
mSpaceManager->Translate(tx, ty);
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
line_end = kid->end_lines();
line != line_end;
@@ -495,7 +511,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
// moving relative to their parent block, only relative to
// the space manager.
RecoverFloats(line, 0);
mSpaceManager->Translate(-kidx, -kidy);
mSpaceManager->Translate(-tx, -ty);
}
}
}
@@ -966,8 +982,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
else {
isLeftFloat = PR_FALSE;
if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.width) {
nsIFrame* prevInFlow;
floatFrame->GetPrevInFlow(&prevInFlow);
if (prevInFlow) {
region.x = prevRect.x;
}

View File

@@ -41,6 +41,7 @@
#include "nsSpaceManager.h"
#include "nsIFontMetrics.h"
#include "nsIPresContext.h"
#include "nsIFrameManager.h"
#include "nsIContent.h"
#include "nsStyleContext.h"
#include "nsHTMLReflowCommand.h"
@@ -291,6 +292,14 @@ ComputeShrinkwrapMargins(const nsStyleMargin* aStyleMargin, nscoord aWidth, nsMa
}
}
static void
nsPointDtor(nsIPresContext *aPresContext, nsIFrame *aFrame,
nsIAtom *aPropertyName, void *aPropertyValue)
{
nsPoint *point = NS_STATIC_CAST(nsPoint*, aPropertyValue);
delete point;
}
nsresult
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
PRBool aApplyTopMargin,
@@ -373,6 +382,23 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
aComputedOffsets = aFrameRS.mComputedOffsets;
if (NS_STYLE_POSITION_RELATIVE == display->mPosition) {
nsIFrameManager *frameManager = mPresContext->GetFrameManager();
nsPoint *offsets;
frameManager->GetFrameProperty(mFrame,
nsLayoutAtoms::computedOffsetProperty, 0,
(void**)&offsets);
if (offsets)
offsets->MoveTo(aComputedOffsets.left, aComputedOffsets.top);
else {
offsets = new nsPoint(aComputedOffsets.left, aComputedOffsets.top);
if (offsets)
frameManager->SetFrameProperty(mFrame,
nsLayoutAtoms::computedOffsetProperty,
offsets, nsPointDtor);
}
}
aFrameRS.mLineLayout = nsnull;
if (!aIsAdjacentWithTop) {
aFrameRS.mFlags.mIsTopOfPage = PR_FALSE; // make sure this is cleared
@@ -452,6 +478,16 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
}
// Compute the translation to be used for adjusting the spacemanagager
// coordinate system for the frame. The spacemanager coordinates are
// <b>inside</b> the callers border+padding, but the x/y coordinates
// are not (recall that frame coordinates are relative to the parents
// origin and that the parents border/padding is <b>inside</b> the
// parent frame. Therefore we have to subtract out the parents
// border+padding before translating.
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
// If the element is relatively positioned, then adjust x and y accordingly
if (NS_STYLE_POSITION_RELATIVE == aFrameRS.mStyleDisplay->mPosition) {
x += aFrameRS.mComputedOffsets.left;
@@ -477,15 +513,6 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
#endif
// Adjust spacemanager coordinate system for the frame. The
// spacemanager coordinates are <b>inside</b> the callers
// border+padding, but the x/y coordinates are not (recall that
// frame coordinates are relative to the parents origin and that the
// parents border/padding is <b>inside</b> the parent
// frame. Therefore we have to subtract out the parents
// border+padding before translating.
nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
mOuterReflowState.mSpaceManager->Translate(tx, ty);
// See if this is the child's initial reflow and we are supposed to

View File

@@ -484,9 +484,25 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
} else if (aLine->IsBlock()) {
nsBlockFrame *kid = nsnull;
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
if (kid) {
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
mSpaceManager->Translate(kidx, kidy);
// don't recover any state inside a block that has its own space
// manager (we don't currently have any blocks like this, though,
// thanks to our use of extra frames for 'overflow')
if (kid && !(kid->GetStateBits() & NS_BLOCK_SPACE_MGR)) {
nscoord tx = kid->mRect.x, ty = kid->mRect.y;
// If the element is relatively positioned, then adjust x and y
// accordingly so that we consider relatively positioned frames
// at their original position.
if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) {
nsPoint *offsets;
if (NS_OK == mPresContext->GetFrameManager()->GetFrameProperty(kid,
nsLayoutAtoms::computedOffsetProperty, 0, (void**)&offsets)) {
tx -= offsets->x;
ty -= offsets->y;
}
}
mSpaceManager->Translate(tx, ty);
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
line_end = kid->end_lines();
line != line_end;
@@ -495,7 +511,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
// moving relative to their parent block, only relative to
// the space manager.
RecoverFloats(line, 0);
mSpaceManager->Translate(-kidx, -kidy);
mSpaceManager->Translate(-tx, -ty);
}
}
}
@@ -966,8 +982,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
else {
isLeftFloat = PR_FALSE;
if (NS_UNCONSTRAINEDSIZE != mAvailSpaceRect.width) {
nsIFrame* prevInFlow;
floatFrame->GetPrevInFlow(&prevInFlow);
if (prevInFlow) {
region.x = prevRect.x;
}