Changed new frame construction code to handle floaters

This commit is contained in:
troy%netscape.com 1998-09-11 04:13:29 +00:00
Родитель 98c507c676
Коммит de1641f3f9
5 изменённых файлов: 80 добавлений и 16 удалений

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

@ -274,7 +274,9 @@ protected:
nsIRenderingContext& aRenderingContext, nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect); const nsRect& aDirtyRect);
nsresult AddNewFrames(nsIFrame*); nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext,
nsIFrame* aFloatedFrame);
nsresult AddNewFrames(nsIPresContext* aPresContext, nsIFrame*);
#ifdef NS_DEBUG #ifdef NS_DEBUG
PRBool IsChild(nsIFrame* aFrame); PRBool IsChild(nsIFrame* aFrame);
@ -1007,7 +1009,7 @@ NS_IMETHODIMP
nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{ {
mHasBeenInitialized = PR_TRUE; mHasBeenInitialized = PR_TRUE;
return AddNewFrames(aChildList); return AddNewFrames(&aPresContext, aChildList);
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -1504,7 +1506,7 @@ nsCSSBlockFrame::ProcessInitialReflow(nsIPresContext* aPresContext)
bulletFrame->SetStyleContext(aPresContext, kidSC); bulletFrame->SetStyleContext(aPresContext, kidSC);
NS_RELEASE(kidSC); NS_RELEASE(kidSC);
// Now go insert the bullet frame // Insert the bullet frame
InsertNewFrame(this, bulletFrame, nsnull); InsertNewFrame(this, bulletFrame, nsnull);
} }
@ -1655,8 +1657,29 @@ nsCSSBlockFrame::ComputeFinalSize(nsCSSBlockReflowState& aState,
NS_ASSERTION(aDesiredRect.width < 1000000, "whoops"); 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 nsresult
nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame) nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame)
{ {
// Get our last line and then get its last child // Get our last line and then get its last child
nsIFrame* lastFrame; nsIFrame* lastFrame;
@ -1682,6 +1705,7 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame)
} }
// Now create some lines for the new frames // Now create some lines for the new frames
nsIFrame* prevFrame = lastFrame;
nsresult rv; nsresult rv;
for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) { for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) {
// See if the child is a block or non-block // See if the child is a block or non-block
@ -1700,6 +1724,25 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame)
PRBool isBlock = PRBool isBlock =
nsCSSLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition); 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 // 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 // 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. // block then make a new line and put the child in that line.
@ -1747,6 +1790,9 @@ nsCSSBlockFrame::AddNewFrames(nsIFrame* aNewFrame)
lastLine->mChildCount++; lastLine->mChildCount++;
pendingInlines++; pendingInlines++;
} }
// Remember the previous frame
prevFrame = frame;
} }
if (0 != pendingInlines) { if (0 != pendingInlines) {
@ -1813,7 +1859,7 @@ nsCSSBlockFrame::FrameAppendedReflow(nsCSSBlockReflowState& aState)
// Add the new frames to the child list, and create new lines. Each // Add the new frames to the child list, and create new lines. Each
// impacted line will be marked dirty // impacted line will be marked dirty
AddNewFrames(firstAppendedFrame); AddNewFrames(aState.mPresContext, firstAppendedFrame);
#endif #endif
// Generate text-run information // Generate text-run information

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

@ -30,13 +30,14 @@
nsresult nsresult
nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent, nsIContent* aContent,
nsIFrame* aParent) nsIFrame* aParent,
nsIFrame* aAnchoredItem)
{ {
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) { if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
nsIFrame* it = new nsPlaceholderFrame(aContent, aParent); nsIFrame* it = new nsPlaceholderFrame(aContent, aParent, aAnchoredItem);
if (nsnull == it) { if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
@ -44,9 +45,12 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult,
return NS_OK; return NS_OK;
} }
nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aAnchoredItem)
: nsFrame(aContent, aParent) : nsFrame(aContent, aParent)
{ {
mAnchoredItem = aAnchoredItem;
} }
nsPlaceholderFrame::~nsPlaceholderFrame() nsPlaceholderFrame::~nsPlaceholderFrame()
@ -143,6 +147,10 @@ nsPlaceholderFrame::InlineReflow(nsCSSLineLayout& aLineLayout,
// Notify our containing block that there's a new floater // Notify our containing block that there's a new floater
container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); 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 // Let line layout know about the floater

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

@ -29,7 +29,8 @@ public:
*/ */
static nsresult NewFrame(nsIFrame** aInstancePtrResult, static nsresult NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent, nsIContent* aContent,
nsIFrame* aParent); nsIFrame* aParent,
nsIFrame* aAnchoredItem = nsnull);
// Returns the associated anchored item // Returns the associated anchored item
nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} nsIFrame* GetAnchoredItem() const {return mAnchoredItem;}
@ -81,7 +82,7 @@ protected:
// Constructor. Takes as arguments the content object and the Frame for // Constructor. Takes as arguments the content object and the Frame for
// the content parent // the content parent
nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aAnchoredItem);
virtual ~nsPlaceholderFrame(); virtual ~nsPlaceholderFrame();
}; };

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

@ -30,13 +30,14 @@
nsresult nsresult
nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent, nsIContent* aContent,
nsIFrame* aParent) nsIFrame* aParent,
nsIFrame* aAnchoredItem)
{ {
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) { if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
nsIFrame* it = new nsPlaceholderFrame(aContent, aParent); nsIFrame* it = new nsPlaceholderFrame(aContent, aParent, aAnchoredItem);
if (nsnull == it) { if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
@ -44,9 +45,12 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult,
return NS_OK; return NS_OK;
} }
nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aAnchoredItem)
: nsFrame(aContent, aParent) : nsFrame(aContent, aParent)
{ {
mAnchoredItem = aAnchoredItem;
} }
nsPlaceholderFrame::~nsPlaceholderFrame() nsPlaceholderFrame::~nsPlaceholderFrame()
@ -143,6 +147,10 @@ nsPlaceholderFrame::InlineReflow(nsCSSLineLayout& aLineLayout,
// Notify our containing block that there's a new floater // Notify our containing block that there's a new floater
container->AddFloater(&presContext, aReflowState, mAnchoredItem, this); 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 // Let line layout know about the floater

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

@ -29,7 +29,8 @@ public:
*/ */
static nsresult NewFrame(nsIFrame** aInstancePtrResult, static nsresult NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent, nsIContent* aContent,
nsIFrame* aParent); nsIFrame* aParent,
nsIFrame* aAnchoredItem = nsnull);
// Returns the associated anchored item // Returns the associated anchored item
nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} nsIFrame* GetAnchoredItem() const {return mAnchoredItem;}
@ -81,7 +82,7 @@ protected:
// Constructor. Takes as arguments the content object and the Frame for // Constructor. Takes as arguments the content object and the Frame for
// the content parent // the content parent
nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aAnchoredItem);
virtual ~nsPlaceholderFrame(); virtual ~nsPlaceholderFrame();
}; };