From 4e1f1783893020dde89e76a033d7ab3d5dea64e9 Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Fri, 11 Sep 1998 04:13:29 +0000 Subject: [PATCH] Changed new frame construction code to handle floaters git-svn-id: svn://10.0.0.236/trunk@9811 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/css/layout/src/nsCSSBlockFrame.cpp | 58 +++++++++++++++++-- mozilla/layout/generic/nsPlaceholderFrame.cpp | 14 ++++- mozilla/layout/generic/nsPlaceholderFrame.h | 5 +- .../html/base/src/nsPlaceholderFrame.cpp | 14 ++++- .../layout/html/base/src/nsPlaceholderFrame.h | 5 +- 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp b/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp index 37d96a01695..39785bcedd4 100644 --- a/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp +++ b/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp @@ -274,7 +274,9 @@ protected: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - nsresult AddNewFrames(nsIFrame*); + nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext, + nsIFrame* aFloatedFrame); + nsresult AddNewFrames(nsIPresContext* aPresContext, nsIFrame*); #ifdef NS_DEBUG PRBool IsChild(nsIFrame* aFrame); @@ -1007,7 +1009,7 @@ NS_IMETHODIMP nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mHasBeenInitialized = PR_TRUE; - return AddNewFrames(aChildList); + return AddNewFrames(&aPresContext, aChildList); } NS_IMETHODIMP @@ -1504,7 +1506,7 @@ nsCSSBlockFrame::ProcessInitialReflow(nsIPresContext* aPresContext) bulletFrame->SetStyleContext(aPresContext, kidSC); NS_RELEASE(kidSC); - // Now go insert the bullet frame + // Insert the bullet frame InsertNewFrame(this, bulletFrame, nsnull); } @@ -1655,8 +1657,29 @@ nsCSSBlockFrame::ComputeFinalSize(nsCSSBlockReflowState& aState, NS_ASSERTION(aDesiredRect.width < 1000000, "whoops"); } +nsPlaceholderFrame* +nsCSSBlockFrame::CreatePlaceholderFrame(nsIPresContext* aPresContext, + nsIFrame* aFloatedFrame) +{ + nsIContent* content; + aFloatedFrame->GetContent(content); + + // XXX We should wrap the floated element in a BODY frame... + nsPlaceholderFrame* placeholder; + nsPlaceholderFrame::NewFrame((nsIFrame**)&placeholder, content, this, aFloatedFrame); + NS_IF_RELEASE(content); + + // Let the placeholder share the same style context as the floated element + nsIStyleContext* kidSC; + aFloatedFrame->GetStyleContext(aPresContext, kidSC); + placeholder->SetStyleContext(aPresContext, kidSC); + NS_RELEASE(kidSC); + + return placeholder; +} + nsresult -nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame) +nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame) { // Get our last line and then get its last child nsIFrame* lastFrame; @@ -1682,7 +1705,8 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame) } // Now create some lines for the new frames - nsresult rv; + nsIFrame* prevFrame = lastFrame; + nsresult rv; for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) { // See if the child is a block or non-block const nsStyleDisplay* kidDisplay; @@ -1700,6 +1724,25 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame) PRBool isBlock = nsCSSLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition); + // See if the element wants to be floated + if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) { + // Create a placeholder frame that will serve as the anchor point. + nsPlaceholderFrame* placeholder = CreatePlaceholderFrame(aPresContext, frame); + // Remove the floated element from the flow, and replace it with the + // placeholder frame + if (nsnull != prevFrame) { + prevFrame->SetNextSibling(placeholder); + } + nsIFrame* nextSibling; + frame->GetNextSibling(nextSibling); + placeholder->SetNextSibling(nextSibling); + frame->SetNextSibling(nsnull); + + // The placeholder frame is always inline + frame = placeholder; + isBlock = PR_FALSE; + } + // If the child is an inline then add it to the lastLine (if it's // an inline line, otherwise make a new line). If the child is a // block then make a new line and put the child in that line. @@ -1747,6 +1790,9 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame) lastLine->mChildCount++; pendingInlines++; } + + // Remember the previous frame + prevFrame = frame; } if (0 != pendingInlines) { @@ -1813,7 +1859,7 @@ nsCSSBlockFrame::FrameAppendedReflow(nsCSSBlockReflowState& aState) // Add the new frames to the child list, and create new lines. Each // impacted line will be marked dirty - AddNewFrames(firstAppendedFrame); + AddNewFrames(aState.mPresContext, firstAppendedFrame); #endif // Generate text-run information diff --git a/mozilla/layout/generic/nsPlaceholderFrame.cpp b/mozilla/layout/generic/nsPlaceholderFrame.cpp index e268a62ce1d..120579ac865 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.cpp +++ b/mozilla/layout/generic/nsPlaceholderFrame.cpp @@ -30,13 +30,14 @@ nsresult nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, nsIContent* aContent, - nsIFrame* aParent) + nsIFrame* aParent, + nsIFrame* aAnchoredItem) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); if (nsnull == aInstancePtrResult) { return NS_ERROR_NULL_POINTER; } - nsIFrame* it = new nsPlaceholderFrame(aContent, aParent); + nsIFrame* it = new nsPlaceholderFrame(aContent, aParent, aAnchoredItem); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -44,9 +45,12 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, return NS_OK; } -nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) +nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame* aAnchoredItem) : nsFrame(aContent, aParent) { + mAnchoredItem = aAnchoredItem; } nsPlaceholderFrame::~nsPlaceholderFrame() @@ -143,6 +147,10 @@ nsPlaceholderFrame::InlineReflow(nsCSSLineLayout& aLineLayout, // Notify our containing block that there's a new floater container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); + + } else if (eReflowReason_Initial == aReflowState.reason) { + // Notify our containing block that there's a new floater + container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); } // Let line layout know about the floater diff --git a/mozilla/layout/generic/nsPlaceholderFrame.h b/mozilla/layout/generic/nsPlaceholderFrame.h index 9eec8d91455..9de9f990d4f 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.h +++ b/mozilla/layout/generic/nsPlaceholderFrame.h @@ -29,7 +29,8 @@ public: */ static nsresult NewFrame(nsIFrame** aInstancePtrResult, nsIContent* aContent, - nsIFrame* aParent); + nsIFrame* aParent, + nsIFrame* aAnchoredItem = nsnull); // Returns the associated anchored item nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} @@ -81,7 +82,7 @@ protected: // Constructor. Takes as arguments the content object and the Frame for // the content parent - nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); + nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aAnchoredItem); virtual ~nsPlaceholderFrame(); }; diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp index e268a62ce1d..120579ac865 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp @@ -30,13 +30,14 @@ nsresult nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, nsIContent* aContent, - nsIFrame* aParent) + nsIFrame* aParent, + nsIFrame* aAnchoredItem) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); if (nsnull == aInstancePtrResult) { return NS_ERROR_NULL_POINTER; } - nsIFrame* it = new nsPlaceholderFrame(aContent, aParent); + nsIFrame* it = new nsPlaceholderFrame(aContent, aParent, aAnchoredItem); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -44,9 +45,12 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, return NS_OK; } -nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) +nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame* aAnchoredItem) : nsFrame(aContent, aParent) { + mAnchoredItem = aAnchoredItem; } nsPlaceholderFrame::~nsPlaceholderFrame() @@ -143,6 +147,10 @@ nsPlaceholderFrame::InlineReflow(nsCSSLineLayout& aLineLayout, // Notify our containing block that there's a new floater container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); + + } else if (eReflowReason_Initial == aReflowState.reason) { + // Notify our containing block that there's a new floater + container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); } // Let line layout know about the floater diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.h b/mozilla/layout/html/base/src/nsPlaceholderFrame.h index 9eec8d91455..9de9f990d4f 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.h +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.h @@ -29,7 +29,8 @@ public: */ static nsresult NewFrame(nsIFrame** aInstancePtrResult, nsIContent* aContent, - nsIFrame* aParent); + nsIFrame* aParent, + nsIFrame* aAnchoredItem = nsnull); // Returns the associated anchored item nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} @@ -81,7 +82,7 @@ protected: // Constructor. Takes as arguments the content object and the Frame for // the content parent - nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); + nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aAnchoredItem); virtual ~nsPlaceholderFrame(); };