From f1cd9a202bb4cee2fd270e2f1ec917e48eab2354 Mon Sep 17 00:00:00 2001 From: "dbaron%fas.harvard.edu" Date: Tue, 15 Feb 2000 04:26:44 +0000 Subject: [PATCH] Fix bug 15428 as suggested by VYV03354@nifty.ne.jp . Stop using 0 as the initial values for min and max of inline box contents so that lines that do not (vertically) contain their own baseline are sized correctly. Also, correctly size BR frames using their line-height (for strict-mode only). Fix bugs 24186, 26996, and 26998 by reworking the quirks-mode line-height handling so that inline elements that do not have text as children (or meet a few other conditions that show the author wants real CSS support) will not increase the size of the line, but will be as close to their correct size as possible without enlarging the line. This fix includes emulation of the strange Nav4/IE quirk that a block's line-height is enforced on the first line of LI elements and the last line of LI, DD, and DT elements. Many of the changes are removing an earlier fix for 24186. r=buster git-svn-id: svn://10.0.0.236/trunk@60795 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/shared/public/nsLayoutAtomList.h | 1 + mozilla/layout/base/nsLayoutAtomList.h | 1 + mozilla/layout/base/public/nsLayoutAtomList.h | 1 + mozilla/layout/generic/nsBRFrame.cpp | 44 +- mozilla/layout/generic/nsBlockFrame.cpp | 2 +- mozilla/layout/generic/nsBlockReflowState.cpp | 2 +- mozilla/layout/generic/nsBlockReflowState.h | 2 +- mozilla/layout/generic/nsLineLayout.cpp | 407 ++++++++---------- mozilla/layout/generic/nsLineLayout.h | 22 +- mozilla/layout/html/base/src/nsBRFrame.cpp | 44 +- mozilla/layout/html/base/src/nsBlockFrame.cpp | 2 +- .../html/base/src/nsBlockReflowState.cpp | 2 +- .../layout/html/base/src/nsBlockReflowState.h | 2 +- mozilla/layout/html/base/src/nsLineLayout.cpp | 407 ++++++++---------- mozilla/layout/html/base/src/nsLineLayout.h | 22 +- 15 files changed, 437 insertions(+), 524 deletions(-) diff --git a/mozilla/content/shared/public/nsLayoutAtomList.h b/mozilla/content/shared/public/nsLayoutAtomList.h index 8be6148b196..8a7f51c96b1 100644 --- a/mozilla/content/shared/public/nsLayoutAtomList.h +++ b/mozilla/content/shared/public/nsLayoutAtomList.h @@ -84,6 +84,7 @@ LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content") // Alphabetical list of frame types LAYOUT_ATOM(areaFrame, "AreaFrame") LAYOUT_ATOM(blockFrame, "BlockFrame") +LAYOUT_ATOM(brFrame, "BRFrame") LAYOUT_ATOM(bulletFrame, "BulletFrame") LAYOUT_ATOM(hrFrame, "HRFrame") LAYOUT_ATOM(htmlFrameInnerFrame, "htmlFrameInnerFrame") diff --git a/mozilla/layout/base/nsLayoutAtomList.h b/mozilla/layout/base/nsLayoutAtomList.h index 8be6148b196..8a7f51c96b1 100644 --- a/mozilla/layout/base/nsLayoutAtomList.h +++ b/mozilla/layout/base/nsLayoutAtomList.h @@ -84,6 +84,7 @@ LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content") // Alphabetical list of frame types LAYOUT_ATOM(areaFrame, "AreaFrame") LAYOUT_ATOM(blockFrame, "BlockFrame") +LAYOUT_ATOM(brFrame, "BRFrame") LAYOUT_ATOM(bulletFrame, "BulletFrame") LAYOUT_ATOM(hrFrame, "HRFrame") LAYOUT_ATOM(htmlFrameInnerFrame, "htmlFrameInnerFrame") diff --git a/mozilla/layout/base/public/nsLayoutAtomList.h b/mozilla/layout/base/public/nsLayoutAtomList.h index 8be6148b196..8a7f51c96b1 100644 --- a/mozilla/layout/base/public/nsLayoutAtomList.h +++ b/mozilla/layout/base/public/nsLayoutAtomList.h @@ -84,6 +84,7 @@ LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content") // Alphabetical list of frame types LAYOUT_ATOM(areaFrame, "AreaFrame") LAYOUT_ATOM(blockFrame, "BlockFrame") +LAYOUT_ATOM(brFrame, "BRFrame") LAYOUT_ATOM(bulletFrame, "BulletFrame") LAYOUT_ATOM(hrFrame, "HRFrame") LAYOUT_ATOM(htmlFrameInnerFrame, "htmlFrameInnerFrame") diff --git a/mozilla/layout/generic/nsBRFrame.cpp b/mozilla/layout/generic/nsBRFrame.cpp index fe4bb608441..6cde1c1d12c 100644 --- a/mozilla/layout/generic/nsBRFrame.cpp +++ b/mozilla/layout/generic/nsBRFrame.cpp @@ -30,6 +30,7 @@ #include "nsIStyleContext.h" #include "nsIFontMetrics.h" #include "nsIRenderingContext.h" +#include "nsLayoutAtoms.h" //FOR SELECTION #include "nsIContent.h" @@ -59,6 +60,7 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); + NS_IMETHOD GetFrameType(nsIAtom** aType) const; protected: virtual ~BRFrame(); }; @@ -110,7 +112,9 @@ BRFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->width = 0; aMetrics.maxElementSize->height = 0; } - aMetrics.height = 0; + aMetrics.height = 0; // BR frames with height 0 are ignored in quirks + // mode by nsLineLayout::VerticalAlignFrames . + // However, it's not always 0. See below. aMetrics.width = 0; aMetrics.ascent = 0; aMetrics.descent = 0; @@ -119,23 +123,41 @@ BRFrame::Reflow(nsIPresContext* aPresContext, // behave like a BR. nsLineLayout* ll = aReflowState.mLineLayout; if (ll) { - if (ll->CanPlaceFloaterNow()) { + if ( ll->CanPlaceFloaterNow() || ll->InStrictMode() ) { // If we can place a floater on the line now it means that the // line is effectively empty (there may be zero sized compressed // white-space frames on the line, but they are to be ignored). // - // Because this frame is going to terminate the line we know + // If this frame is going to terminate the line we know // that nothing else will go on the line. Therefore, in this - // case only, we provide some height for the BR frame so that it - // creates some vertical whitespace. + // case, we provide some height for the BR frame so that it + // creates some vertical whitespace. It's necessary to use the + // line-height rather than the font size because the + // quirks-mode fix that doesn't apply the block's min + // line-height makes this necessary to make BR cause a line + // of the full line-height + + // We also do this in strict mode because BR should act like a + // normal inline frame. That line-height is used is important + // here for cases where the line-height is less that 1. const nsStyleFont* font = (const nsStyleFont*) mStyleContext->GetStyleData(eStyleStruct_Font); aReflowState.rendContext->SetFont(font->mFont); nsCOMPtr fm; aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); if (fm) { - fm->GetHeight(aMetrics.height); - aMetrics.ascent = aMetrics.height; + nscoord ascent, descent; + fm->GetMaxAscent(ascent); + fm->GetMaxDescent(descent); + nscoord logicalHeight = + aReflowState.CalcLineHeight(aPresContext, + aReflowState.rendContext, + this); + nscoord leading = logicalHeight - ascent - descent; + aMetrics.height = logicalHeight; + aMetrics.ascent = ascent + (leading/2); + aMetrics.descent = logicalHeight - aMetrics.ascent; + // = descent + (leading/2), but without rounding error } else { aMetrics.ascent = aMetrics.height = 0; @@ -174,6 +196,14 @@ BRFrame::Reflow(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +BRFrame::GetFrameType(nsIAtom** aType) const +{ + NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); + *aType = nsLayoutAtoms::brFrame; + NS_ADDREF(*aType); + return NS_OK; +} NS_IMETHODIMP BRFrame::GetContentAndOffsetsFromPoint(nsIPresContext* aCX, const nsPoint& aPoint, diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 94d6dd9fdb2..79575ce17d7 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -19,6 +19,7 @@ * * Contributor(s): * Pierre Phaneuf + * L. David Baron */ #include "nsCOMPtr.h" #include "nsLineLayout.h" @@ -36,10 +37,10 @@ #include "nsIDocument.h" #include "nsIHTMLDocument.h" #include "nsIContent.h" +#include "nsITextContent.h" #include "nsIView.h" #include "nsIViewManager.h" -#include "nsHTMLAtoms.h" -#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" #ifdef DEBUG #undef NOISY_HORIZONTAL_ALIGN @@ -493,7 +494,6 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult) psd->mLastFrame = nsnull; psd->mContainsFloater = PR_FALSE; psd->mZeroEffectiveSpanBox = PR_FALSE; - psd->mIgnoreMinLineHeight = PR_FALSE; #ifdef DEBUG mSpansAllocated++; @@ -774,6 +774,7 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult) pfd->mRelativePos = PR_FALSE; pfd->mIsTextFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; @@ -980,6 +981,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, pfd->mIsTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus); @@ -1017,8 +1019,23 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, else if (frameType == nsLayoutAtoms::textFrame) { // Note non-empty text-frames for inline frame compatability hackery pfd->mIsTextFrame = PR_TRUE; + // XXX An empty text frame at the end of the line seems not + // to have zero width. if (metrics.width) { pfd->mIsNonEmptyTextFrame = PR_TRUE; + nsCOMPtr content; + nsresult result = pfd->mFrame->GetContent(getter_AddRefs(content)); + if ((NS_SUCCEEDED(result)) && content) { + nsCOMPtr textContent + = do_QueryInterface(content, &result); + if ((NS_SUCCEEDED(result)) && textContent) { + PRBool isWhitespace; + result = textContent->IsOnlyWhitespace(&isWhitespace); + if (NS_SUCCEEDED(result)) { + pfd->mIsNonWhitespaceTextFrame = !isWhitespace; + } + } + } } } else if (frameType == nsLayoutAtoms::letterFrame) { @@ -1502,6 +1519,7 @@ nsLineLayout::AddBulletFrame(nsIFrame* aFrame, pfd->mDescent = aMetrics.descent; pfd->mIsTextFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; @@ -1541,7 +1559,7 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent) #define VALIGN_BOTTOM 2 void -nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, +nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult) { // Synthesize a PerFrameData for the block frame @@ -1551,6 +1569,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, rootPFD.mAscent = 0; rootPFD.mDescent = 0; mRootSpan->mFrame = &rootPFD; + mLineBox = aLineBox; // Partially place the children of the block frame. The baseline for // this operation is set to zero so that the y coordinates for all @@ -1581,29 +1600,6 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, baselineY = mTopEdge; } - // It's possible that the line-height isn't tall enough because of - // the blocks minimum line-height. - if (!psd->mZeroEffectiveSpanBox) { - if (0 != lineHeight) { - // If line contains nothing but empty boxes that have no height - // then don't apply the min-line-height. - // - // Note: This is how we hide lines that contain nothing but - // compressed whitespace. - if (PR_FALSE==psd->mIgnoreMinLineHeight) { // factor in min line height (part of bug 24186) - if (lineHeight < mMinLineHeight) { - // Apply half of the extra space to the top of the line as top - // leading - nscoord extra = mMinLineHeight - lineHeight; - baselineY += extra / 2; - lineHeight = mMinLineHeight; - } - } - // XXX else...I think this is where we need code to sniff out the underlying - // line height as given by the child , in quirks mode. rest of 24186 - } - } - // It's also possible that the line-height isn't tall enough because // of top/bottom aligned elements that were not accounted for in // min/max Y. @@ -1627,7 +1623,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, lineHeight = mMaxTopBoxHeight; } #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> lineHeight=%d baselineY=%d\n", lineHeight, baselineY); + printf(" [line]==> lineHeight=%d baselineY=%d\n", lineHeight, baselineY); #endif // Now position all of the frames in the root span. We will also @@ -1684,7 +1680,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, } pfd->mFrame->SetRect(mPresContext, pfd->mBounds); #ifdef NOISY_VERTICAL_ALIGN - printf(" "); + printf(" [child of line]"); nsFrame::ListTag(stdout, pfd->mFrame); printf(": y=%d\n", pfd->mBounds.y); #endif @@ -1696,16 +1692,17 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, } // Fill in returned line-box and max-element-size data - aLineBoxResult.x = psd->mLeftEdge; - aLineBoxResult.y = mTopEdge; - aLineBoxResult.width = psd->mX - psd->mLeftEdge; - aLineBoxResult.height = lineHeight; + aLineBox->mBounds.x = psd->mLeftEdge; + aLineBox->mBounds.y = mTopEdge; + aLineBox->mBounds.width = psd->mX - psd->mLeftEdge; + aLineBox->mBounds.height = lineHeight; mFinalLineHeight = lineHeight; aMaxElementSizeResult.width = maxElementWidth; aMaxElementSizeResult.height = maxElementHeight; // Undo root-span mFrame pointer to prevent brane damage later on... mRootSpan->mFrame = nsnull; + mLineBox = nsnull; } void @@ -1765,85 +1762,8 @@ nsLineLayout::PlaceTopBottomFrames(PerSpanData* psd, } } - -/* assumptions: - (1) we're in quirks mode - (2) aFrame in an inline frame, and cannot contain block frames - - what we do: - (1) look for covering every text frame that decends from aFrame - - results: - if all conditions are met, - set aOutResult to PR_TRUE - set aPSD->mQuirksModeFontMetrics to the largest font found - - to do: - (2) look for explicit line height setting -*/ -void -nsLineLayout::ComputeQuirksModeLineHeightData(nsIRenderingContext *aRC, - PerSpanData *aPSD, - nsIFrame *aFrame, - PRBool *aOutResult) -{ - if (!aOutResult) return; - *aOutResult = PR_FALSE; - if (!aFrame || !aRC) return; //note, aPSD can be null - - nsCOMPtr largestFont; - nsIFrame *spanFrameWithLargestFont = aFrame; - - nsCOMPtr content; - aFrame->GetContent(getter_AddRefs(content)); - if (content) - { - nsCOMPtr tag; - content->GetTag(*(getter_AddRefs(tag))); - if (nsHTMLAtoms::font==tag.get()) - { - nsAutoString resultString; - nsresult result; - result = content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::size, resultString); - if (NS_CONTENT_ATTR_HAS_VALUE==result) - { - *aOutResult = PR_TRUE; - } - } - // if we didn't find it, let's check out it's children - if (PR_FALSE==*aOutResult) - { - // ComputeQuirksModeLineHeightData of all in-flow children - PRBool childResult = PR_FALSE; - nsIFrame *child; - aFrame->FirstChild(mPresContext, nsnull, &child); - while (child) - { - ComputeQuirksModeLineHeightData(aRC, aPSD, child, &childResult); - if (PR_FALSE==childResult) { - break; // a child failed, bail - } - spanFrameWithLargestFont = child; // that's dumb for now, need to really compute this - child->GetNextSibling(&child); - } - *aOutResult = childResult; // only true if all children returned true - } - } - - // if we found a font, set the font to be used in quirks-mode line height calculation - // if the caller requested us to (by passing in a non-null aPSD - if (PR_TRUE==*aOutResult && aPSD) - { - NS_ASSERTION(spanFrameWithLargestFont, "failed to compute spanFrameWithLargestFont"); - if (!spanFrameWithLargestFont) - return; - const nsStyleFont* font; - spanFrameWithLargestFont->GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font); - aRC->SetFont(font->mFont); - // this is wrong, we should be setting this to the largest (tallest) font - aRC->GetFontMetrics(*getter_AddRefs(aPSD->mQuirksModeFontMetrics)); - } -} +#define VERTICAL_ALIGN_FRAMES_NO_MINIMUM 32767 +#define VERTICAL_ALIGN_FRAMES_NO_MAXIMUM -32768 // Vertically place frames within a given span. Note: this doesn't // place top/bottom aligned frames as those have to wait until the @@ -1880,6 +1800,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) (0 == spanFramePFD->mBounds.width) && (0 == spanFramePFD->mBounds.height); #ifdef NOISY_VERTICAL_ALIGN + printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); printf(": preMode=%s strictMode=%s w/h=%d,%d emptyContinuation=%s", preMode ? "yes" : "no", @@ -1938,23 +1859,17 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // where the font-size and line-height for a span must be // ignored and instead the span must *act* as if it were zero // sized. In general, if the span contains any non-compressed - // text or contains another span which contains non-compressed - // text, then we don't use this logic. + // text then we don't use this logic. + // However, this is not propogated outwards, since (in compatibility + // mode) we don't want big line heights for things like + //

Text

zeroEffectiveSpanBox = PR_TRUE; PerFrameData* pfd = psd->mFirstFrame; while (nsnull != pfd) { - if (pfd->mIsNonEmptyTextFrame) { + if (pfd->mIsNonWhitespaceTextFrame) { zeroEffectiveSpanBox = PR_FALSE; break; } - PerSpanData* frameSpan = pfd->mSpan; - if (frameSpan) { - if (!frameSpan->mZeroEffectiveSpanBox) { - // Propogate prescence of non-empty text outward - zeroEffectiveSpanBox = PR_FALSE; - break; - } - } pfd = pfd->mNext; } } @@ -1969,8 +1884,11 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // values so that only the child frames will impact their values // (since these are children of the block, there is no span box to // provide initial values). - baselineY = minY = maxY = 0; + baselineY = 0; + minY = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + maxY = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; #ifdef NOISY_VERTICAL_ALIGN + printf("[RootSpan]"); nsFrame::ListTag(stdout, spanFrame); printf(": pass1 valign frames: topEdge=%d minLineHeight=%d zeroEffectiveSpanBox=%s\n", mTopEdge, mMinLineHeight, @@ -1978,30 +1896,30 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) #endif } else { + // Compute the logical height for this span. The logical height + // is based on the line-height value, not the font-size. Also + // compute the top leading. + nscoord logicalHeight = + nsHTMLReflowState::CalcLineHeight(mPresContext, rc, spanFrame); + nscoord contentHeight = spanFramePFD->mBounds.height - + spanFramePFD->mBorderPadding.top - spanFramePFD->mBorderPadding.bottom; + nscoord leading = logicalHeight - contentHeight; + psd->mTopLeading = leading / 2; + psd->mBottomLeading = leading - psd->mTopLeading; + psd->mLogicalHeight = logicalHeight; + if (zeroEffectiveSpanBox) { - // When the span-box is to be ignored, zero out all the initial + // When the span-box is to be ignored, zero out the initial // values so that the span doesn't impact the final line // height. The contents of the span can impact the final line // height. - psd->mTopLeading = 0; - psd->mBottomLeading = 0; - psd->mLogicalHeight = 0; - spanFramePFD->mAscent = 0; - spanFramePFD->mBounds.height = 0; - baselineY = minY = maxY = 0; + + // Note that things are readjusted for this span after its children + // are reflowed + minY = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + maxY = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; } else { - // Compute the logical height for this span. The logical height - // is based on the line-height value, not the font-size. Also - // compute the top leading. - nscoord logicalHeight = - nsHTMLReflowState::CalcLineHeight(mPresContext, rc, spanFrame); - nscoord contentHeight = spanFramePFD->mBounds.height - - spanFramePFD->mBorderPadding.top - spanFramePFD->mBorderPadding.bottom; - nscoord leading = logicalHeight - contentHeight; - psd->mTopLeading = leading / 2; - psd->mBottomLeading = leading - psd->mTopLeading; - psd->mLogicalHeight = logicalHeight; // The initial values for the min and max Y values are in the spans // coordinate space, and cover the logical height of the span. If @@ -2010,13 +1928,16 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // height that is outside this range. minY = spanFramePFD->mBorderPadding.top - psd->mTopLeading; maxY = minY + psd->mLogicalHeight; - - // This is the distance from the top edge of the parents visual - // box to the baseline. The span already computed this for us, - // so just use it. - baselineY = spanFramePFD->mAscent; } + + // This is the distance from the top edge of the parents visual + // box to the baseline. The span already computed this for us, + // so just use it. + baselineY = spanFramePFD->mAscent; + + #ifdef NOISY_VERTICAL_ALIGN + printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); printf(": baseLine=%d logicalHeight=%d topLeading=%d h=%d bp=%d,%d zeroEffectiveSpanBox=%s\n", baselineY, psd->mLogicalHeight, psd->mTopLeading, @@ -2062,7 +1983,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } #endif #ifdef NOISY_VERTICAL_ALIGN - printf(" "); + printf(" [frame]"); nsFrame::ListTag(stdout, frame); printf(": verticalAlignUnit=%d (enum == %d)\n", verticalAlignUnit, @@ -2255,10 +2176,21 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) yTop = pfd->mBounds.y - pfd->mMargin.top; yBottom = yTop + logicalHeight; } + if (!preMode && !InStrictMode() && !logicalHeight ) { + // Check if it's a BR frame that is not alone on its line (it + // is given a height of zero to indicate this), and if so reset + // yTop and yBottom so that BR frames don't influence the line. + nsCOMPtr frameType; + frame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::brFrame == frameType.get()) { + yTop = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + yBottom = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; + } + } if (yTop < minY) minY = yTop; if (yBottom > maxY) maxY = yBottom; #ifdef NOISY_VERTICAL_ALIGN - printf(" raw: a=%d d=%d h=%d bp=%d,%d logical: h=%d leading=%d y=%d minY=%d maxY=%d\n", + printf(" [frame]raw: a=%d d=%d h=%d bp=%d,%d logical: h=%d leading=%d y=%d minY=%d maxY=%d\n", pfd->mAscent, pfd->mDescent, pfd->mBounds.height, pfd->mBorderPadding.top, pfd->mBorderPadding.bottom, logicalHeight, @@ -2273,89 +2205,54 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) pfd = pfd->mNext; } - /* This is where we fix bug 24186. - * In quirks mode only, in some situations we want to ignore the - * minimum line height on the parent block. - * We set psd->mIgnoreMinLineHeight as a result of this logic: - 0) in standard mode? - psd->mIgnoreMinLineHeight=false, stop - 1) does the block have an explicit line height? - psd->mIgnoreMinLineHeight=false, stop - 2) examine each frame in the span. - if all text frames are entirely enclosed by a tag - psd->mIgnoreMinLineHeight=true - 3) otherwise, iMLH=false - - * To Do: - * a) cache this computation - */ - if (psd == mRootSpan) - { - psd->mIgnoreMinLineHeight=PR_TRUE; // we'll set this to false in all the right places... - if (InStrictMode()) - { // we're in standard mode - psd->mIgnoreMinLineHeight = PR_FALSE; // (0) - } - else - { - // test to see if the block has an explicit line height set - nsIFrame *blockFrame = nsnull; - if (psd->mFrame) - { - blockFrame = psd->mFrame->mFrame; - nsCOMPtr sc; - blockFrame->GetStyleContext(getter_AddRefs(sc)); - if (sc) - { - const nsStyleText* text = (const nsStyleText*) - sc->GetStyleData(eStyleStruct_Text); - if (text && eStyleUnit_Normal != text->mLineHeight.GetUnit()) - { - psd->mIgnoreMinLineHeight = PR_FALSE; // (1) - } - } - } - // finally, look at each span in the block, and see if a line height is set - // or a is found. For now, just look at - if (PR_TRUE==psd->mIgnoreMinLineHeight) - { - // abc PRBool ignore=PR_FALSE; - PRBool ignore=PR_TRUE; - PerFrameData* pfd = psd->mFirstFrame; - while (nsnull != pfd) - { - ComputeQuirksModeLineHeightData(rc, psd, pfd->mFrame, &ignore); - // abc if (PR_TRUE==ignore) { // we found one, short-circuit the loop - if (PR_FALSE==ignore) { // we found one, short-circuit the loop - break; - } - pfd = pfd->mNext; - } - psd->mIgnoreMinLineHeight = ignore; // (2) and (3) - } - } - } - // Factor in the minimum line-height when handling the root-span for // the block. if (psd == mRootSpan) { - // If this span's width is non-zero then it can't possibly be a - // line that contains nothing but zero width items. Therefore we - // should factor in the block element's minimum line-height (as - // defined in section 10.8.1 of the css2 spec). - if (psd->mZeroEffectiveSpanBox) { - // Leave minY/maxY values untouched + // We should factor in the block element's minimum line-height (as + // defined in section 10.8.1 of the css2 spec) assuming that + // mZeroEffectiveSpanBox is not set on the root span. This only happens + // in some cases in quirks mode: + // (1) if the root span contains non-whitespace text directly (this + // is handled by mZeroEffectiveSpanBox + // (2) if this is the first line of an LI element (whether or not + // there is a bullet (NN4/IE5 quirk) + // (3) if this is the last line of an LI, DT, or DD element + // (The last line before a block also counts, but not before a + // BR) (NN4/IE5 quirk) + PRBool applyMinLH = !(psd->mZeroEffectiveSpanBox); // (1) above + PRBool isFirstLine = !mLineNumber; // if the line number is 0 + PRBool isLastLine = (!mLineBox->IsLineWrapped() && !mLineEndsInBR); + //PRBool isLastLine = mBlockRS->mCurLine->IsLineWrapped(); + if (!applyMinLH && (isFirstLine || isLastLine)) { + nsCOMPtr blockContent; + nsresult result = mRootSpan->mFrame->mFrame->GetContent(getter_AddRefs(blockContent)); + if ( NS_SUCCEEDED(result) && blockContent) { + nsCOMPtr blockTagAtom; + result = blockContent->GetTag(*(getter_AddRefs(blockTagAtom))); + // XXX There aren't atoms for dd and dt, so I'm converting to + // a string. Is that the right thing to do? + if ( NS_SUCCEEDED(result) && blockTagAtom) { + nsAutoString blockTag; + blockTagAtom->ToString(blockTag); + // (2) above, if the first line of LI + if (isFirstLine && blockTag.Equals("li")) { + applyMinLH = PR_TRUE; + } + // (3) above, if the last line of LI, DT, or DD + if (!applyMinLH && isLastLine && (blockTag.Equals("li") || + blockTag.Equals("dt") || + blockTag.Equals("dd"))) { + applyMinLH = PR_TRUE; + } + } + } } - else { + if (applyMinLH) { if ((psd->mX != psd->mLeftEdge) || preMode) { #ifdef NOISY_VERTICAL_ALIGN - printf(" ignoreMinLH = %d\n", psd->mIgnoreMinLineHeight); - printf(" ==> adjusting min/maxY: currentValues: %d,%d", minY, maxY); + printf(" [span]==> adjusting min/maxY: currentValues: %d,%d", minY, maxY); #endif - nscoord minimumLineHeight = 0; - if (PR_FALSE==psd->mIgnoreMinLineHeight) { - minimumLineHeight = mMinLineHeight; - } + nscoord minimumLineHeight = mMinLineHeight; nscoord fontAscent, fontHeight; fm->GetMaxAscent(fontAscent); if (nsHTMLReflowState::UseComputedHeight()) { @@ -2363,13 +2260,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } else { - if (PR_TRUE==psd->mIgnoreMinLineHeight) { - psd->mQuirksModeFontMetrics->GetHeight(fontHeight); - psd->mQuirksModeFontMetrics->GetMaxAscent(fontAscent); - } - else { - fm->GetHeight(fontHeight); - } + fm->GetHeight(fontHeight); } nscoord leading = minimumLineHeight - fontHeight; @@ -2388,7 +2279,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // [2] May not honor css2's notion of handling empty elements // [3] blank lines in a pre-section ("\n") (handled with preMode) #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> zapping min/maxY: currentValues: %d,%d newValues: 0,0\n", + printf(" [span]==> zapping min/maxY: currentValues: %d,%d newValues: 0,0\n", minY, maxY); #endif minY = maxY = 0; @@ -2396,10 +2287,58 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } } + if ((minY == VERTICAL_ALIGN_FRAMES_NO_MINIMUM) || + (maxY == VERTICAL_ALIGN_FRAMES_NO_MINIMUM)) { + minY = maxY = 0; + } + + if ((psd != mRootSpan) && (psd->mZeroEffectiveSpanBox)) { + nscoord goodMinY = spanFramePFD->mBorderPadding.top - psd->mTopLeading; + nscoord goodMaxY = goodMinY + psd->mLogicalHeight; + if (minY > goodMinY) { + nscoord adjust = minY - goodMinY; // positive + + // shrink the logical extents + psd->mLogicalHeight -= adjust; + psd->mTopLeading -= adjust; + } + if (maxY < goodMaxY) { + nscoord adjust = goodMaxY - maxY; + psd->mLogicalHeight -= adjust; + psd->mBottomLeading -= adjust; + } + if (minY > 0) { + + // shrink the content by moving its top down. This is tricky, since + // the top is the 0 for many coordinates, so what we do is + // move everything else up. + spanFramePFD->mAscent -= minY; // move the baseline up + spanFramePFD->mBounds.height -= minY; // move the bottom up + //spanFrame->SetRect(mPresContext, spanFramePFD->mBounds); + psd->mTopLeading += minY; + + pfd = psd->mFirstFrame; + while (nsnull != pfd) { + pfd->mBounds.y -= minY; // move all the children back up + pfd->mFrame->SetRect(mPresContext, pfd->mBounds); + pfd = pfd->mNext; + } + maxY -= minY; // since minY is in the frame's own coordinate system + minY = 0; + } + if ((maxY - minY) < spanFramePFD->mBounds.height) { + nscoord adjust = spanFramePFD->mBounds.height - maxY + minY; + spanFramePFD->mBounds.height -= adjust; // move the bottom up + //spanFrame->SetRect(mPresContext, spanFramePFD->mBounds); + spanFramePFD->mDescent -= adjust; + psd->mBottomLeading += adjust; + } + } + psd->mMinY = minY; psd->mMaxY = maxY; #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> minY=%d maxY=%d delta=%d maxTopBoxHeight=%d maxBottomBoxHeight=%d\n", + printf(" [span]==> minY=%d maxY=%d delta=%d maxTopBoxHeight=%d maxBottomBoxHeight=%d\n", minY, maxY, maxY - minY, maxTopBoxHeight, maxBottomBoxHeight); #endif if (maxTopBoxHeight > mMaxTopBoxHeight) { diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index 5b50ffbdb2f..2cb644817ba 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -25,8 +25,7 @@ #include "nsFrame.h" #include "nsVoidArray.h" #include "nsTextRun.h" -#include "nsIFontMetrics.h" -#include "nsCOMPtr.h" +#include "nsLineBox.h" class nsISpaceManager; class nsBlockReflowState; @@ -110,7 +109,7 @@ public: PushFrame(aFrame); } - void VerticalAlignFrames(nsRect& aLineBoxResult, + void VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult); PRBool TrimTrailingWhiteSpace(); @@ -234,6 +233,7 @@ protected: nsIFrame* mFirstLetterFrame; PRInt32 mLineNumber; PRInt32 mColumn; + nsLineBox* mLineBox; PRPackedBool mEndsInWhiteSpace; PRPackedBool mUnderstandsWhiteSpace; PRPackedBool mTextStartsWithNBSP; @@ -300,6 +300,7 @@ protected: PRUint8 mVerticalAlign; PRPackedBool mIsTextFrame; PRPackedBool mIsNonEmptyTextFrame; + PRPackedBool mIsNonWhitespaceTextFrame; PRPackedBool mIsLetterFrame; PRPackedBool mIsSticky; @@ -333,8 +334,6 @@ public: PRPackedBool mChangedFrameDirection; PRPackedBool mZeroEffectiveSpanBox; PRPackedBool mContainsFloater; - PRPackedBool mIgnoreMinLineHeight; - nsCOMPtr mQuirksModeFontMetrics; nscoord mLeftEdge; nscoord mX; @@ -402,19 +401,6 @@ protected: void VerticalAlignFrames(PerSpanData* psd); - /** compute the data needed to adjust the line height (in VerticalAlignFrames) - * primarily in quirks (Nav4 compatibility) mode. - * @param aRC the rendering context for the span - * @param aPSD PerSpanData object for the current span - * @param aFrame the frame at which the computation should begin - * @param aIgnore [OUT] PR_TRUE indicates that the block's min height should be ignored - * PR_FALSE indicates that the block's min height still has effect - */ - void ComputeQuirksModeLineHeightData(nsIRenderingContext *aRC, - PerSpanData *aPSD, - nsIFrame *aFrame, - PRBool *aIgnore); - void PlaceTopBottomFrames(PerSpanData* psd, nscoord aDistanceFromTop, nscoord aLineHeight); diff --git a/mozilla/layout/html/base/src/nsBRFrame.cpp b/mozilla/layout/html/base/src/nsBRFrame.cpp index fe4bb608441..6cde1c1d12c 100644 --- a/mozilla/layout/html/base/src/nsBRFrame.cpp +++ b/mozilla/layout/html/base/src/nsBRFrame.cpp @@ -30,6 +30,7 @@ #include "nsIStyleContext.h" #include "nsIFontMetrics.h" #include "nsIRenderingContext.h" +#include "nsLayoutAtoms.h" //FOR SELECTION #include "nsIContent.h" @@ -59,6 +60,7 @@ public: nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); + NS_IMETHOD GetFrameType(nsIAtom** aType) const; protected: virtual ~BRFrame(); }; @@ -110,7 +112,9 @@ BRFrame::Reflow(nsIPresContext* aPresContext, aMetrics.maxElementSize->width = 0; aMetrics.maxElementSize->height = 0; } - aMetrics.height = 0; + aMetrics.height = 0; // BR frames with height 0 are ignored in quirks + // mode by nsLineLayout::VerticalAlignFrames . + // However, it's not always 0. See below. aMetrics.width = 0; aMetrics.ascent = 0; aMetrics.descent = 0; @@ -119,23 +123,41 @@ BRFrame::Reflow(nsIPresContext* aPresContext, // behave like a BR. nsLineLayout* ll = aReflowState.mLineLayout; if (ll) { - if (ll->CanPlaceFloaterNow()) { + if ( ll->CanPlaceFloaterNow() || ll->InStrictMode() ) { // If we can place a floater on the line now it means that the // line is effectively empty (there may be zero sized compressed // white-space frames on the line, but they are to be ignored). // - // Because this frame is going to terminate the line we know + // If this frame is going to terminate the line we know // that nothing else will go on the line. Therefore, in this - // case only, we provide some height for the BR frame so that it - // creates some vertical whitespace. + // case, we provide some height for the BR frame so that it + // creates some vertical whitespace. It's necessary to use the + // line-height rather than the font size because the + // quirks-mode fix that doesn't apply the block's min + // line-height makes this necessary to make BR cause a line + // of the full line-height + + // We also do this in strict mode because BR should act like a + // normal inline frame. That line-height is used is important + // here for cases where the line-height is less that 1. const nsStyleFont* font = (const nsStyleFont*) mStyleContext->GetStyleData(eStyleStruct_Font); aReflowState.rendContext->SetFont(font->mFont); nsCOMPtr fm; aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); if (fm) { - fm->GetHeight(aMetrics.height); - aMetrics.ascent = aMetrics.height; + nscoord ascent, descent; + fm->GetMaxAscent(ascent); + fm->GetMaxDescent(descent); + nscoord logicalHeight = + aReflowState.CalcLineHeight(aPresContext, + aReflowState.rendContext, + this); + nscoord leading = logicalHeight - ascent - descent; + aMetrics.height = logicalHeight; + aMetrics.ascent = ascent + (leading/2); + aMetrics.descent = logicalHeight - aMetrics.ascent; + // = descent + (leading/2), but without rounding error } else { aMetrics.ascent = aMetrics.height = 0; @@ -174,6 +196,14 @@ BRFrame::Reflow(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +BRFrame::GetFrameType(nsIAtom** aType) const +{ + NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer"); + *aType = nsLayoutAtoms::brFrame; + NS_ADDREF(*aType); + return NS_OK; +} NS_IMETHODIMP BRFrame::GetContentAndOffsetsFromPoint(nsIPresContext* aCX, const nsPoint& aPoint, diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index ec698bc6867..c5091a32110 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -4264,7 +4264,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; - aLineLayout.VerticalAlignFrames(aLine->mBounds, maxElementSize); + aLineLayout.VerticalAlignFrames(aLine, maxElementSize); // See if we're shrink wrapping the width if (aState.mShrinkWrapWidth) { // When determining the line's width we also need to include any diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index 94d6dd9fdb2..79575ce17d7 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -19,6 +19,7 @@ * * Contributor(s): * Pierre Phaneuf + * L. David Baron */ #include "nsCOMPtr.h" #include "nsLineLayout.h" @@ -36,10 +37,10 @@ #include "nsIDocument.h" #include "nsIHTMLDocument.h" #include "nsIContent.h" +#include "nsITextContent.h" #include "nsIView.h" #include "nsIViewManager.h" -#include "nsHTMLAtoms.h" -#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" #ifdef DEBUG #undef NOISY_HORIZONTAL_ALIGN @@ -493,7 +494,6 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult) psd->mLastFrame = nsnull; psd->mContainsFloater = PR_FALSE; psd->mZeroEffectiveSpanBox = PR_FALSE; - psd->mIgnoreMinLineHeight = PR_FALSE; #ifdef DEBUG mSpansAllocated++; @@ -774,6 +774,7 @@ nsLineLayout::NewPerFrameData(PerFrameData** aResult) pfd->mRelativePos = PR_FALSE; pfd->mIsTextFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; @@ -980,6 +981,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, pfd->mIsTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; aFrame->Reflow(mPresContext, metrics, reflowState, aReflowStatus); @@ -1017,8 +1019,23 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, else if (frameType == nsLayoutAtoms::textFrame) { // Note non-empty text-frames for inline frame compatability hackery pfd->mIsTextFrame = PR_TRUE; + // XXX An empty text frame at the end of the line seems not + // to have zero width. if (metrics.width) { pfd->mIsNonEmptyTextFrame = PR_TRUE; + nsCOMPtr content; + nsresult result = pfd->mFrame->GetContent(getter_AddRefs(content)); + if ((NS_SUCCEEDED(result)) && content) { + nsCOMPtr textContent + = do_QueryInterface(content, &result); + if ((NS_SUCCEEDED(result)) && textContent) { + PRBool isWhitespace; + result = textContent->IsOnlyWhitespace(&isWhitespace); + if (NS_SUCCEEDED(result)) { + pfd->mIsNonWhitespaceTextFrame = !isWhitespace; + } + } + } } } else if (frameType == nsLayoutAtoms::letterFrame) { @@ -1502,6 +1519,7 @@ nsLineLayout::AddBulletFrame(nsIFrame* aFrame, pfd->mDescent = aMetrics.descent; pfd->mIsTextFrame = PR_FALSE; pfd->mIsNonEmptyTextFrame = PR_FALSE; + pfd->mIsNonWhitespaceTextFrame = PR_FALSE; pfd->mIsLetterFrame = PR_FALSE; pfd->mIsSticky = PR_FALSE; @@ -1541,7 +1559,7 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent) #define VALIGN_BOTTOM 2 void -nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, +nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult) { // Synthesize a PerFrameData for the block frame @@ -1551,6 +1569,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, rootPFD.mAscent = 0; rootPFD.mDescent = 0; mRootSpan->mFrame = &rootPFD; + mLineBox = aLineBox; // Partially place the children of the block frame. The baseline for // this operation is set to zero so that the y coordinates for all @@ -1581,29 +1600,6 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, baselineY = mTopEdge; } - // It's possible that the line-height isn't tall enough because of - // the blocks minimum line-height. - if (!psd->mZeroEffectiveSpanBox) { - if (0 != lineHeight) { - // If line contains nothing but empty boxes that have no height - // then don't apply the min-line-height. - // - // Note: This is how we hide lines that contain nothing but - // compressed whitespace. - if (PR_FALSE==psd->mIgnoreMinLineHeight) { // factor in min line height (part of bug 24186) - if (lineHeight < mMinLineHeight) { - // Apply half of the extra space to the top of the line as top - // leading - nscoord extra = mMinLineHeight - lineHeight; - baselineY += extra / 2; - lineHeight = mMinLineHeight; - } - } - // XXX else...I think this is where we need code to sniff out the underlying - // line height as given by the child , in quirks mode. rest of 24186 - } - } - // It's also possible that the line-height isn't tall enough because // of top/bottom aligned elements that were not accounted for in // min/max Y. @@ -1627,7 +1623,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, lineHeight = mMaxTopBoxHeight; } #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> lineHeight=%d baselineY=%d\n", lineHeight, baselineY); + printf(" [line]==> lineHeight=%d baselineY=%d\n", lineHeight, baselineY); #endif // Now position all of the frames in the root span. We will also @@ -1684,7 +1680,7 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, } pfd->mFrame->SetRect(mPresContext, pfd->mBounds); #ifdef NOISY_VERTICAL_ALIGN - printf(" "); + printf(" [child of line]"); nsFrame::ListTag(stdout, pfd->mFrame); printf(": y=%d\n", pfd->mBounds.y); #endif @@ -1696,16 +1692,17 @@ nsLineLayout::VerticalAlignFrames(nsRect& aLineBoxResult, } // Fill in returned line-box and max-element-size data - aLineBoxResult.x = psd->mLeftEdge; - aLineBoxResult.y = mTopEdge; - aLineBoxResult.width = psd->mX - psd->mLeftEdge; - aLineBoxResult.height = lineHeight; + aLineBox->mBounds.x = psd->mLeftEdge; + aLineBox->mBounds.y = mTopEdge; + aLineBox->mBounds.width = psd->mX - psd->mLeftEdge; + aLineBox->mBounds.height = lineHeight; mFinalLineHeight = lineHeight; aMaxElementSizeResult.width = maxElementWidth; aMaxElementSizeResult.height = maxElementHeight; // Undo root-span mFrame pointer to prevent brane damage later on... mRootSpan->mFrame = nsnull; + mLineBox = nsnull; } void @@ -1765,85 +1762,8 @@ nsLineLayout::PlaceTopBottomFrames(PerSpanData* psd, } } - -/* assumptions: - (1) we're in quirks mode - (2) aFrame in an inline frame, and cannot contain block frames - - what we do: - (1) look for covering every text frame that decends from aFrame - - results: - if all conditions are met, - set aOutResult to PR_TRUE - set aPSD->mQuirksModeFontMetrics to the largest font found - - to do: - (2) look for explicit line height setting -*/ -void -nsLineLayout::ComputeQuirksModeLineHeightData(nsIRenderingContext *aRC, - PerSpanData *aPSD, - nsIFrame *aFrame, - PRBool *aOutResult) -{ - if (!aOutResult) return; - *aOutResult = PR_FALSE; - if (!aFrame || !aRC) return; //note, aPSD can be null - - nsCOMPtr largestFont; - nsIFrame *spanFrameWithLargestFont = aFrame; - - nsCOMPtr content; - aFrame->GetContent(getter_AddRefs(content)); - if (content) - { - nsCOMPtr tag; - content->GetTag(*(getter_AddRefs(tag))); - if (nsHTMLAtoms::font==tag.get()) - { - nsAutoString resultString; - nsresult result; - result = content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::size, resultString); - if (NS_CONTENT_ATTR_HAS_VALUE==result) - { - *aOutResult = PR_TRUE; - } - } - // if we didn't find it, let's check out it's children - if (PR_FALSE==*aOutResult) - { - // ComputeQuirksModeLineHeightData of all in-flow children - PRBool childResult = PR_FALSE; - nsIFrame *child; - aFrame->FirstChild(mPresContext, nsnull, &child); - while (child) - { - ComputeQuirksModeLineHeightData(aRC, aPSD, child, &childResult); - if (PR_FALSE==childResult) { - break; // a child failed, bail - } - spanFrameWithLargestFont = child; // that's dumb for now, need to really compute this - child->GetNextSibling(&child); - } - *aOutResult = childResult; // only true if all children returned true - } - } - - // if we found a font, set the font to be used in quirks-mode line height calculation - // if the caller requested us to (by passing in a non-null aPSD - if (PR_TRUE==*aOutResult && aPSD) - { - NS_ASSERTION(spanFrameWithLargestFont, "failed to compute spanFrameWithLargestFont"); - if (!spanFrameWithLargestFont) - return; - const nsStyleFont* font; - spanFrameWithLargestFont->GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font); - aRC->SetFont(font->mFont); - // this is wrong, we should be setting this to the largest (tallest) font - aRC->GetFontMetrics(*getter_AddRefs(aPSD->mQuirksModeFontMetrics)); - } -} +#define VERTICAL_ALIGN_FRAMES_NO_MINIMUM 32767 +#define VERTICAL_ALIGN_FRAMES_NO_MAXIMUM -32768 // Vertically place frames within a given span. Note: this doesn't // place top/bottom aligned frames as those have to wait until the @@ -1880,6 +1800,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) (0 == spanFramePFD->mBounds.width) && (0 == spanFramePFD->mBounds.height); #ifdef NOISY_VERTICAL_ALIGN + printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); printf(": preMode=%s strictMode=%s w/h=%d,%d emptyContinuation=%s", preMode ? "yes" : "no", @@ -1938,23 +1859,17 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // where the font-size and line-height for a span must be // ignored and instead the span must *act* as if it were zero // sized. In general, if the span contains any non-compressed - // text or contains another span which contains non-compressed - // text, then we don't use this logic. + // text then we don't use this logic. + // However, this is not propogated outwards, since (in compatibility + // mode) we don't want big line heights for things like + //

Text

zeroEffectiveSpanBox = PR_TRUE; PerFrameData* pfd = psd->mFirstFrame; while (nsnull != pfd) { - if (pfd->mIsNonEmptyTextFrame) { + if (pfd->mIsNonWhitespaceTextFrame) { zeroEffectiveSpanBox = PR_FALSE; break; } - PerSpanData* frameSpan = pfd->mSpan; - if (frameSpan) { - if (!frameSpan->mZeroEffectiveSpanBox) { - // Propogate prescence of non-empty text outward - zeroEffectiveSpanBox = PR_FALSE; - break; - } - } pfd = pfd->mNext; } } @@ -1969,8 +1884,11 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // values so that only the child frames will impact their values // (since these are children of the block, there is no span box to // provide initial values). - baselineY = minY = maxY = 0; + baselineY = 0; + minY = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + maxY = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; #ifdef NOISY_VERTICAL_ALIGN + printf("[RootSpan]"); nsFrame::ListTag(stdout, spanFrame); printf(": pass1 valign frames: topEdge=%d minLineHeight=%d zeroEffectiveSpanBox=%s\n", mTopEdge, mMinLineHeight, @@ -1978,30 +1896,30 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) #endif } else { + // Compute the logical height for this span. The logical height + // is based on the line-height value, not the font-size. Also + // compute the top leading. + nscoord logicalHeight = + nsHTMLReflowState::CalcLineHeight(mPresContext, rc, spanFrame); + nscoord contentHeight = spanFramePFD->mBounds.height - + spanFramePFD->mBorderPadding.top - spanFramePFD->mBorderPadding.bottom; + nscoord leading = logicalHeight - contentHeight; + psd->mTopLeading = leading / 2; + psd->mBottomLeading = leading - psd->mTopLeading; + psd->mLogicalHeight = logicalHeight; + if (zeroEffectiveSpanBox) { - // When the span-box is to be ignored, zero out all the initial + // When the span-box is to be ignored, zero out the initial // values so that the span doesn't impact the final line // height. The contents of the span can impact the final line // height. - psd->mTopLeading = 0; - psd->mBottomLeading = 0; - psd->mLogicalHeight = 0; - spanFramePFD->mAscent = 0; - spanFramePFD->mBounds.height = 0; - baselineY = minY = maxY = 0; + + // Note that things are readjusted for this span after its children + // are reflowed + minY = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + maxY = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; } else { - // Compute the logical height for this span. The logical height - // is based on the line-height value, not the font-size. Also - // compute the top leading. - nscoord logicalHeight = - nsHTMLReflowState::CalcLineHeight(mPresContext, rc, spanFrame); - nscoord contentHeight = spanFramePFD->mBounds.height - - spanFramePFD->mBorderPadding.top - spanFramePFD->mBorderPadding.bottom; - nscoord leading = logicalHeight - contentHeight; - psd->mTopLeading = leading / 2; - psd->mBottomLeading = leading - psd->mTopLeading; - psd->mLogicalHeight = logicalHeight; // The initial values for the min and max Y values are in the spans // coordinate space, and cover the logical height of the span. If @@ -2010,13 +1928,16 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // height that is outside this range. minY = spanFramePFD->mBorderPadding.top - psd->mTopLeading; maxY = minY + psd->mLogicalHeight; - - // This is the distance from the top edge of the parents visual - // box to the baseline. The span already computed this for us, - // so just use it. - baselineY = spanFramePFD->mAscent; } + + // This is the distance from the top edge of the parents visual + // box to the baseline. The span already computed this for us, + // so just use it. + baselineY = spanFramePFD->mAscent; + + #ifdef NOISY_VERTICAL_ALIGN + printf("[%sSpan]", (psd == mRootSpan)?"Root":""); nsFrame::ListTag(stdout, spanFrame); printf(": baseLine=%d logicalHeight=%d topLeading=%d h=%d bp=%d,%d zeroEffectiveSpanBox=%s\n", baselineY, psd->mLogicalHeight, psd->mTopLeading, @@ -2062,7 +1983,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } #endif #ifdef NOISY_VERTICAL_ALIGN - printf(" "); + printf(" [frame]"); nsFrame::ListTag(stdout, frame); printf(": verticalAlignUnit=%d (enum == %d)\n", verticalAlignUnit, @@ -2255,10 +2176,21 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) yTop = pfd->mBounds.y - pfd->mMargin.top; yBottom = yTop + logicalHeight; } + if (!preMode && !InStrictMode() && !logicalHeight ) { + // Check if it's a BR frame that is not alone on its line (it + // is given a height of zero to indicate this), and if so reset + // yTop and yBottom so that BR frames don't influence the line. + nsCOMPtr frameType; + frame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::brFrame == frameType.get()) { + yTop = VERTICAL_ALIGN_FRAMES_NO_MINIMUM; + yBottom = VERTICAL_ALIGN_FRAMES_NO_MAXIMUM; + } + } if (yTop < minY) minY = yTop; if (yBottom > maxY) maxY = yBottom; #ifdef NOISY_VERTICAL_ALIGN - printf(" raw: a=%d d=%d h=%d bp=%d,%d logical: h=%d leading=%d y=%d minY=%d maxY=%d\n", + printf(" [frame]raw: a=%d d=%d h=%d bp=%d,%d logical: h=%d leading=%d y=%d minY=%d maxY=%d\n", pfd->mAscent, pfd->mDescent, pfd->mBounds.height, pfd->mBorderPadding.top, pfd->mBorderPadding.bottom, logicalHeight, @@ -2273,89 +2205,54 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) pfd = pfd->mNext; } - /* This is where we fix bug 24186. - * In quirks mode only, in some situations we want to ignore the - * minimum line height on the parent block. - * We set psd->mIgnoreMinLineHeight as a result of this logic: - 0) in standard mode? - psd->mIgnoreMinLineHeight=false, stop - 1) does the block have an explicit line height? - psd->mIgnoreMinLineHeight=false, stop - 2) examine each frame in the span. - if all text frames are entirely enclosed by a tag - psd->mIgnoreMinLineHeight=true - 3) otherwise, iMLH=false - - * To Do: - * a) cache this computation - */ - if (psd == mRootSpan) - { - psd->mIgnoreMinLineHeight=PR_TRUE; // we'll set this to false in all the right places... - if (InStrictMode()) - { // we're in standard mode - psd->mIgnoreMinLineHeight = PR_FALSE; // (0) - } - else - { - // test to see if the block has an explicit line height set - nsIFrame *blockFrame = nsnull; - if (psd->mFrame) - { - blockFrame = psd->mFrame->mFrame; - nsCOMPtr sc; - blockFrame->GetStyleContext(getter_AddRefs(sc)); - if (sc) - { - const nsStyleText* text = (const nsStyleText*) - sc->GetStyleData(eStyleStruct_Text); - if (text && eStyleUnit_Normal != text->mLineHeight.GetUnit()) - { - psd->mIgnoreMinLineHeight = PR_FALSE; // (1) - } - } - } - // finally, look at each span in the block, and see if a line height is set - // or a is found. For now, just look at - if (PR_TRUE==psd->mIgnoreMinLineHeight) - { - // abc PRBool ignore=PR_FALSE; - PRBool ignore=PR_TRUE; - PerFrameData* pfd = psd->mFirstFrame; - while (nsnull != pfd) - { - ComputeQuirksModeLineHeightData(rc, psd, pfd->mFrame, &ignore); - // abc if (PR_TRUE==ignore) { // we found one, short-circuit the loop - if (PR_FALSE==ignore) { // we found one, short-circuit the loop - break; - } - pfd = pfd->mNext; - } - psd->mIgnoreMinLineHeight = ignore; // (2) and (3) - } - } - } - // Factor in the minimum line-height when handling the root-span for // the block. if (psd == mRootSpan) { - // If this span's width is non-zero then it can't possibly be a - // line that contains nothing but zero width items. Therefore we - // should factor in the block element's minimum line-height (as - // defined in section 10.8.1 of the css2 spec). - if (psd->mZeroEffectiveSpanBox) { - // Leave minY/maxY values untouched + // We should factor in the block element's minimum line-height (as + // defined in section 10.8.1 of the css2 spec) assuming that + // mZeroEffectiveSpanBox is not set on the root span. This only happens + // in some cases in quirks mode: + // (1) if the root span contains non-whitespace text directly (this + // is handled by mZeroEffectiveSpanBox + // (2) if this is the first line of an LI element (whether or not + // there is a bullet (NN4/IE5 quirk) + // (3) if this is the last line of an LI, DT, or DD element + // (The last line before a block also counts, but not before a + // BR) (NN4/IE5 quirk) + PRBool applyMinLH = !(psd->mZeroEffectiveSpanBox); // (1) above + PRBool isFirstLine = !mLineNumber; // if the line number is 0 + PRBool isLastLine = (!mLineBox->IsLineWrapped() && !mLineEndsInBR); + //PRBool isLastLine = mBlockRS->mCurLine->IsLineWrapped(); + if (!applyMinLH && (isFirstLine || isLastLine)) { + nsCOMPtr blockContent; + nsresult result = mRootSpan->mFrame->mFrame->GetContent(getter_AddRefs(blockContent)); + if ( NS_SUCCEEDED(result) && blockContent) { + nsCOMPtr blockTagAtom; + result = blockContent->GetTag(*(getter_AddRefs(blockTagAtom))); + // XXX There aren't atoms for dd and dt, so I'm converting to + // a string. Is that the right thing to do? + if ( NS_SUCCEEDED(result) && blockTagAtom) { + nsAutoString blockTag; + blockTagAtom->ToString(blockTag); + // (2) above, if the first line of LI + if (isFirstLine && blockTag.Equals("li")) { + applyMinLH = PR_TRUE; + } + // (3) above, if the last line of LI, DT, or DD + if (!applyMinLH && isLastLine && (blockTag.Equals("li") || + blockTag.Equals("dt") || + blockTag.Equals("dd"))) { + applyMinLH = PR_TRUE; + } + } + } } - else { + if (applyMinLH) { if ((psd->mX != psd->mLeftEdge) || preMode) { #ifdef NOISY_VERTICAL_ALIGN - printf(" ignoreMinLH = %d\n", psd->mIgnoreMinLineHeight); - printf(" ==> adjusting min/maxY: currentValues: %d,%d", minY, maxY); + printf(" [span]==> adjusting min/maxY: currentValues: %d,%d", minY, maxY); #endif - nscoord minimumLineHeight = 0; - if (PR_FALSE==psd->mIgnoreMinLineHeight) { - minimumLineHeight = mMinLineHeight; - } + nscoord minimumLineHeight = mMinLineHeight; nscoord fontAscent, fontHeight; fm->GetMaxAscent(fontAscent); if (nsHTMLReflowState::UseComputedHeight()) { @@ -2363,13 +2260,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } else { - if (PR_TRUE==psd->mIgnoreMinLineHeight) { - psd->mQuirksModeFontMetrics->GetHeight(fontHeight); - psd->mQuirksModeFontMetrics->GetMaxAscent(fontAscent); - } - else { - fm->GetHeight(fontHeight); - } + fm->GetHeight(fontHeight); } nscoord leading = minimumLineHeight - fontHeight; @@ -2388,7 +2279,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // [2] May not honor css2's notion of handling empty elements // [3] blank lines in a pre-section ("\n") (handled with preMode) #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> zapping min/maxY: currentValues: %d,%d newValues: 0,0\n", + printf(" [span]==> zapping min/maxY: currentValues: %d,%d newValues: 0,0\n", minY, maxY); #endif minY = maxY = 0; @@ -2396,10 +2287,58 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) } } + if ((minY == VERTICAL_ALIGN_FRAMES_NO_MINIMUM) || + (maxY == VERTICAL_ALIGN_FRAMES_NO_MINIMUM)) { + minY = maxY = 0; + } + + if ((psd != mRootSpan) && (psd->mZeroEffectiveSpanBox)) { + nscoord goodMinY = spanFramePFD->mBorderPadding.top - psd->mTopLeading; + nscoord goodMaxY = goodMinY + psd->mLogicalHeight; + if (minY > goodMinY) { + nscoord adjust = minY - goodMinY; // positive + + // shrink the logical extents + psd->mLogicalHeight -= adjust; + psd->mTopLeading -= adjust; + } + if (maxY < goodMaxY) { + nscoord adjust = goodMaxY - maxY; + psd->mLogicalHeight -= adjust; + psd->mBottomLeading -= adjust; + } + if (minY > 0) { + + // shrink the content by moving its top down. This is tricky, since + // the top is the 0 for many coordinates, so what we do is + // move everything else up. + spanFramePFD->mAscent -= minY; // move the baseline up + spanFramePFD->mBounds.height -= minY; // move the bottom up + //spanFrame->SetRect(mPresContext, spanFramePFD->mBounds); + psd->mTopLeading += minY; + + pfd = psd->mFirstFrame; + while (nsnull != pfd) { + pfd->mBounds.y -= minY; // move all the children back up + pfd->mFrame->SetRect(mPresContext, pfd->mBounds); + pfd = pfd->mNext; + } + maxY -= minY; // since minY is in the frame's own coordinate system + minY = 0; + } + if ((maxY - minY) < spanFramePFD->mBounds.height) { + nscoord adjust = spanFramePFD->mBounds.height - maxY + minY; + spanFramePFD->mBounds.height -= adjust; // move the bottom up + //spanFrame->SetRect(mPresContext, spanFramePFD->mBounds); + spanFramePFD->mDescent -= adjust; + psd->mBottomLeading += adjust; + } + } + psd->mMinY = minY; psd->mMaxY = maxY; #ifdef NOISY_VERTICAL_ALIGN - printf(" ==> minY=%d maxY=%d delta=%d maxTopBoxHeight=%d maxBottomBoxHeight=%d\n", + printf(" [span]==> minY=%d maxY=%d delta=%d maxTopBoxHeight=%d maxBottomBoxHeight=%d\n", minY, maxY, maxY - minY, maxTopBoxHeight, maxBottomBoxHeight); #endif if (maxTopBoxHeight > mMaxTopBoxHeight) { diff --git a/mozilla/layout/html/base/src/nsLineLayout.h b/mozilla/layout/html/base/src/nsLineLayout.h index 5b50ffbdb2f..2cb644817ba 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.h +++ b/mozilla/layout/html/base/src/nsLineLayout.h @@ -25,8 +25,7 @@ #include "nsFrame.h" #include "nsVoidArray.h" #include "nsTextRun.h" -#include "nsIFontMetrics.h" -#include "nsCOMPtr.h" +#include "nsLineBox.h" class nsISpaceManager; class nsBlockReflowState; @@ -110,7 +109,7 @@ public: PushFrame(aFrame); } - void VerticalAlignFrames(nsRect& aLineBoxResult, + void VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult); PRBool TrimTrailingWhiteSpace(); @@ -234,6 +233,7 @@ protected: nsIFrame* mFirstLetterFrame; PRInt32 mLineNumber; PRInt32 mColumn; + nsLineBox* mLineBox; PRPackedBool mEndsInWhiteSpace; PRPackedBool mUnderstandsWhiteSpace; PRPackedBool mTextStartsWithNBSP; @@ -300,6 +300,7 @@ protected: PRUint8 mVerticalAlign; PRPackedBool mIsTextFrame; PRPackedBool mIsNonEmptyTextFrame; + PRPackedBool mIsNonWhitespaceTextFrame; PRPackedBool mIsLetterFrame; PRPackedBool mIsSticky; @@ -333,8 +334,6 @@ public: PRPackedBool mChangedFrameDirection; PRPackedBool mZeroEffectiveSpanBox; PRPackedBool mContainsFloater; - PRPackedBool mIgnoreMinLineHeight; - nsCOMPtr mQuirksModeFontMetrics; nscoord mLeftEdge; nscoord mX; @@ -402,19 +401,6 @@ protected: void VerticalAlignFrames(PerSpanData* psd); - /** compute the data needed to adjust the line height (in VerticalAlignFrames) - * primarily in quirks (Nav4 compatibility) mode. - * @param aRC the rendering context for the span - * @param aPSD PerSpanData object for the current span - * @param aFrame the frame at which the computation should begin - * @param aIgnore [OUT] PR_TRUE indicates that the block's min height should be ignored - * PR_FALSE indicates that the block's min height still has effect - */ - void ComputeQuirksModeLineHeightData(nsIRenderingContext *aRC, - PerSpanData *aPSD, - nsIFrame *aFrame, - PRBool *aIgnore); - void PlaceTopBottomFrames(PerSpanData* psd, nscoord aDistanceFromTop, nscoord aLineHeight);