From 5a0f716ef35c92b4c4d2aebc3d1cca2211d20d30 Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Fri, 29 Oct 1999 14:34:01 +0000 Subject: [PATCH] r=troy; fixed letter frame logic to use the line layout to flow frames so that white-space trimming, for example, would work right git-svn-id: svn://10.0.0.236/trunk@52212 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsFirstLetterFrame.cpp | 68 +++++++++++++------ .../html/base/src/nsFirstLetterFrame.cpp | 68 +++++++++++++------ 2 files changed, 94 insertions(+), 42 deletions(-) diff --git a/mozilla/layout/generic/nsFirstLetterFrame.cpp b/mozilla/layout/generic/nsFirstLetterFrame.cpp index 1e667fd6c15..35fcd26d706 100644 --- a/mozilla/layout/generic/nsFirstLetterFrame.cpp +++ b/mozilla/layout/generic/nsFirstLetterFrame.cpp @@ -16,9 +16,12 @@ * Corporation. Portions created by Netscape are Copyright (C) 1998 * Netscape Communications Corporation. All Rights Reserved. */ +#include "nsCOMPtr.h" #include "nsHTMLContainerFrame.h" #include "nsIPresContext.h" #include "nsIStyleContext.h" +#include "nsIReflowCommand.h" +#include "nsIContent.h" #include "nsLineLayout.h" #include "nsHTMLAtoms.h" #include "nsHTMLIIDs.h" @@ -139,7 +142,9 @@ nsFirstLetterFrame::SetInitialChildList(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFrames.SetFrames(aChildList); - aPresContext.ReParentStyleContext(aChildList, mStyleContext); // XXX only first frame? + if (aChildList) { + aPresContext.ReParentStyleContext(aChildList, mStyleContext); + } return NS_OK; } @@ -164,14 +169,19 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aReflowStatus) { + nsresult rv = NS_OK; + // Grab overflow list DrainOverflowFrames(&aPresContext); nsIFrame* kid = mFrames.FirstChild(); - nsIHTMLReflow* htmlReflow; - nsresult rv = kid->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow); - if (NS_FAILED(rv)) { - return rv; + nsIFrame* nextRCFrame = nsnull; + if (aReflowState.reason == eReflowReason_Incremental) { + nsIFrame* target; + aReflowState.reflowCommand->GetTarget(target); + if (this != target) { + aReflowState.reflowCommand->GetNext(nextRCFrame); + } } // Setup reflow state for our child @@ -183,36 +193,39 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, availSize.width -= lr; } if (NS_UNCONSTRAINEDSIZE != availSize.height) { - availSize.width -= tb; + availSize.height -= tb; } // Reflow the child - nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); - htmlReflow->WillReflow(aPresContext); - if (!rs.mLineLayout) { + if (!aReflowState.mLineLayout) { // When there is no lineLayout provided, we provide our own. The // only time that the first-letter-frame is not reflowing in a // line context is when its floating. + nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); nsLineLayout ll(aPresContext, nsnull, &aReflowState, nsnull != aMetrics.maxElementSize); ll.BeginLineReflow(0, 0, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE, PR_FALSE, PR_TRUE); rs.mLineLayout = ≪ ll.SetFirstLetterStyleOK(PR_TRUE); + + nsIHTMLReflow* htmlReflow; + rv = kid->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow); + if (NS_FAILED(rv)) { + return rv; + } + htmlReflow->WillReflow(aPresContext); htmlReflow->Reflow(aPresContext, aMetrics, rs, aReflowStatus); + ll.EndLineReflow(); } else { -// XXX currently the block code sets this up; see comment in -// ReflowInlineFrames -#if XXX - // Only the first-in-flow frame of a first-letter frame gets the - // special first-letter reflow treatment. - if (!mPrevInFlow) { - rs.mLineLayout->SetFirstLetterStyleOK(PR_TRUE); - } -#endif - htmlReflow->Reflow(aPresContext, aMetrics, rs, aReflowStatus); + // Pretend we are a span and reflow the child frame + nsLineLayout* ll = aReflowState.mLineLayout; + ll->BeginSpan(this, &aReflowState, bp.left, availSize.width); + ll->ReflowFrame(kid, &nextRCFrame, aReflowStatus, &aMetrics); + nsSize size; + ll->EndSpan(this, size, aMetrics.maxElementSize); } // Place and size the child and update the output metrics @@ -220,6 +233,8 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height); aMetrics.width += lr; aMetrics.height += tb; + aMetrics.ascent += bp.top; + aMetrics.descent += bp.bottom; if (aMetrics.maxElementSize) { aMetrics.maxElementSize->width += lr; aMetrics.maxElementSize->height += tb; @@ -292,9 +307,20 @@ nsFirstLetterFrame::DrainOverflowFrames(nsIPresContext* aPresContext) mFrames.AppendFrames(nsnull, overflowFrames); } - // Now repair our first frames style context XXX only first frame? + // Now repair our first frames style context (since we only reflow + // one frame there is no point in doing any other ones until they + // are reflowed) nsIFrame* kid = mFrames.FirstChild(); if (kid) { - aPresContext->ReParentStyleContext(kid, mStyleContext); + nsCOMPtr sc; + nsCOMPtr kidContent; + kid->GetContent(getter_AddRefs(kidContent)); + if (kidContent) { + aPresContext->ResolveStyleContextFor(kidContent, mStyleContext, + PR_FALSE, getter_AddRefs(sc)); + if (sc) { + kid->SetStyleContext(aPresContext, sc); + } + } } } diff --git a/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp b/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp index 1e667fd6c15..35fcd26d706 100644 --- a/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp +++ b/mozilla/layout/html/base/src/nsFirstLetterFrame.cpp @@ -16,9 +16,12 @@ * Corporation. Portions created by Netscape are Copyright (C) 1998 * Netscape Communications Corporation. All Rights Reserved. */ +#include "nsCOMPtr.h" #include "nsHTMLContainerFrame.h" #include "nsIPresContext.h" #include "nsIStyleContext.h" +#include "nsIReflowCommand.h" +#include "nsIContent.h" #include "nsLineLayout.h" #include "nsHTMLAtoms.h" #include "nsHTMLIIDs.h" @@ -139,7 +142,9 @@ nsFirstLetterFrame::SetInitialChildList(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFrames.SetFrames(aChildList); - aPresContext.ReParentStyleContext(aChildList, mStyleContext); // XXX only first frame? + if (aChildList) { + aPresContext.ReParentStyleContext(aChildList, mStyleContext); + } return NS_OK; } @@ -164,14 +169,19 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aReflowStatus) { + nsresult rv = NS_OK; + // Grab overflow list DrainOverflowFrames(&aPresContext); nsIFrame* kid = mFrames.FirstChild(); - nsIHTMLReflow* htmlReflow; - nsresult rv = kid->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow); - if (NS_FAILED(rv)) { - return rv; + nsIFrame* nextRCFrame = nsnull; + if (aReflowState.reason == eReflowReason_Incremental) { + nsIFrame* target; + aReflowState.reflowCommand->GetTarget(target); + if (this != target) { + aReflowState.reflowCommand->GetNext(nextRCFrame); + } } // Setup reflow state for our child @@ -183,36 +193,39 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, availSize.width -= lr; } if (NS_UNCONSTRAINEDSIZE != availSize.height) { - availSize.width -= tb; + availSize.height -= tb; } // Reflow the child - nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); - htmlReflow->WillReflow(aPresContext); - if (!rs.mLineLayout) { + if (!aReflowState.mLineLayout) { // When there is no lineLayout provided, we provide our own. The // only time that the first-letter-frame is not reflowing in a // line context is when its floating. + nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize); nsLineLayout ll(aPresContext, nsnull, &aReflowState, nsnull != aMetrics.maxElementSize); ll.BeginLineReflow(0, 0, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE, PR_FALSE, PR_TRUE); rs.mLineLayout = ≪ ll.SetFirstLetterStyleOK(PR_TRUE); + + nsIHTMLReflow* htmlReflow; + rv = kid->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow); + if (NS_FAILED(rv)) { + return rv; + } + htmlReflow->WillReflow(aPresContext); htmlReflow->Reflow(aPresContext, aMetrics, rs, aReflowStatus); + ll.EndLineReflow(); } else { -// XXX currently the block code sets this up; see comment in -// ReflowInlineFrames -#if XXX - // Only the first-in-flow frame of a first-letter frame gets the - // special first-letter reflow treatment. - if (!mPrevInFlow) { - rs.mLineLayout->SetFirstLetterStyleOK(PR_TRUE); - } -#endif - htmlReflow->Reflow(aPresContext, aMetrics, rs, aReflowStatus); + // Pretend we are a span and reflow the child frame + nsLineLayout* ll = aReflowState.mLineLayout; + ll->BeginSpan(this, &aReflowState, bp.left, availSize.width); + ll->ReflowFrame(kid, &nextRCFrame, aReflowStatus, &aMetrics); + nsSize size; + ll->EndSpan(this, size, aMetrics.maxElementSize); } // Place and size the child and update the output metrics @@ -220,6 +233,8 @@ nsFirstLetterFrame::Reflow(nsIPresContext& aPresContext, kid->SizeTo(&aPresContext, aMetrics.width, aMetrics.height); aMetrics.width += lr; aMetrics.height += tb; + aMetrics.ascent += bp.top; + aMetrics.descent += bp.bottom; if (aMetrics.maxElementSize) { aMetrics.maxElementSize->width += lr; aMetrics.maxElementSize->height += tb; @@ -292,9 +307,20 @@ nsFirstLetterFrame::DrainOverflowFrames(nsIPresContext* aPresContext) mFrames.AppendFrames(nsnull, overflowFrames); } - // Now repair our first frames style context XXX only first frame? + // Now repair our first frames style context (since we only reflow + // one frame there is no point in doing any other ones until they + // are reflowed) nsIFrame* kid = mFrames.FirstChild(); if (kid) { - aPresContext->ReParentStyleContext(kid, mStyleContext); + nsCOMPtr sc; + nsCOMPtr kidContent; + kid->GetContent(getter_AddRefs(kidContent)); + if (kidContent) { + aPresContext->ResolveStyleContextFor(kidContent, mStyleContext, + PR_FALSE, getter_AddRefs(sc)); + if (sc) { + kid->SetStyleContext(aPresContext, sc); + } + } } }