From 918b4d93c16645be95cd304973011685ce43a3d0 Mon Sep 17 00:00:00 2001 From: "rbs%maths.uq.edu.au" Date: Mon, 5 Jun 2000 08:24:18 +0000 Subject: [PATCH] [#ifdef MOZ_MATHML: not yet part of default build]. Export the baseline out of the block frame code to support 'vertical-align: baseline' in table-cells. bug 10207. r:buster@netscape.com. a:waterson@mozilla.org git-svn-id: svn://10.0.0.236/trunk@71513 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsBlockFrame.cpp | 53 +++++++++++++++++++ mozilla/layout/generic/nsBlockFrame.h | 11 ++++ mozilla/layout/generic/nsBlockReflowState.cpp | 53 +++++++++++++++++++ mozilla/layout/generic/nsBlockReflowState.h | 53 +++++++++++++++++++ mozilla/layout/generic/nsLineLayout.cpp | 10 ++++ mozilla/layout/generic/nsLineLayout.h | 6 +++ mozilla/layout/html/base/src/nsBlockFrame.cpp | 53 +++++++++++++++++++ mozilla/layout/html/base/src/nsBlockFrame.h | 11 ++++ .../html/base/src/nsBlockReflowState.cpp | 53 +++++++++++++++++++ .../layout/html/base/src/nsBlockReflowState.h | 53 +++++++++++++++++++ mozilla/layout/html/base/src/nsLineLayout.cpp | 10 ++++ mozilla/layout/html/base/src/nsLineLayout.h | 6 +++ 12 files changed, 372 insertions(+) diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index 0845df9b0b5..f266abf24db 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -163,6 +163,12 @@ public: nsLineBox* FindLineFor(nsIFrame* aFrame, nsLineBox** aPrevLineResult, PRBool* aIsFloaterResult); +#ifdef MOZ_MATHML + // return our ascent (i.e., ascent of our first line) + // to support 'vertical-align: baseline' in table-cells + nscoord GetAscent() const; +#endif + protected: nsBlockFrame(); virtual ~nsBlockFrame(); @@ -424,6 +430,11 @@ protected: PRInt32 GetDepth() const; #endif +#ifdef MOZ_MATHML + // Ascent of our first line to support 'vertical-align: baseline' in table-cells + nscoord mAscent; +#endif + nsLineBox* mLines; // Text run information diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 082925542c6..a4986c04c7b 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -1539,9 +1539,16 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent) #define VALIGN_TOP 1 #define VALIGN_BOTTOM 2 +#ifndef MOZ_MATHML void nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult) +#else +void +nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, + nsSize& aMaxElementSizeResult, + nscoord& aLineBoxAscent) +#endif { // Synthesize a PerFrameData for the block frame PerFrameData rootPFD; @@ -1680,6 +1687,9 @@ nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, mFinalLineHeight = lineHeight; aMaxElementSizeResult.width = maxElementWidth; aMaxElementSizeResult.height = maxElementHeight; +#ifdef MOZ_MATHML + aLineBoxAscent = baselineY; +#endif // Undo root-span mFrame pointer to prevent brane damage later on... mRootSpan->mFrame = nsnull; diff --git a/mozilla/layout/generic/nsLineLayout.h b/mozilla/layout/generic/nsLineLayout.h index 01ee96fbffd..4a2e4c2b100 100644 --- a/mozilla/layout/generic/nsLineLayout.h +++ b/mozilla/layout/generic/nsLineLayout.h @@ -117,8 +117,14 @@ public: PushFrame(aFrame); } +#ifndef MOZ_MATHML void VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult); +#else + void VerticalAlignFrames(nsLineBox* aLineBox, + nsSize& aMaxElementSizeResult, + nscoord& aLineBoxAscent); +#endif PRBool TrimTrailingWhiteSpace(); diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/html/base/src/nsBlockFrame.h b/mozilla/layout/html/base/src/nsBlockFrame.h index 0845df9b0b5..f266abf24db 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.h +++ b/mozilla/layout/html/base/src/nsBlockFrame.h @@ -163,6 +163,12 @@ public: nsLineBox* FindLineFor(nsIFrame* aFrame, nsLineBox** aPrevLineResult, PRBool* aIsFloaterResult); +#ifdef MOZ_MATHML + // return our ascent (i.e., ascent of our first line) + // to support 'vertical-align: baseline' in table-cells + nscoord GetAscent() const; +#endif + protected: nsBlockFrame(); virtual ~nsBlockFrame(); @@ -424,6 +430,11 @@ protected: PRInt32 GetDepth() const; #endif +#ifdef MOZ_MATHML + // Ascent of our first line to support 'vertical-align: baseline' in table-cells + nscoord mAscent; +#endif + nsLineBox* mLines; // Text run information diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index 2ba4c8772cd..69290105435 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -1072,6 +1072,17 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, // coordinate. nscoord finalDeltaY = newLineY - aLine->mBounds.y; mBlock->SlideLine(*this, aLine, finalDeltaY); +#ifdef MOZ_MATHML + // aLine has been slided, but... + // XXX it is not necessary to worry about the ascent of mBlock here, right? + // Indeed, depending on the status of the first line of mBlock, we can either have: + // case first line of mBlock is dirty : it will be reflowed by mBlock and so + // mBlock->mAscent will be recomputed by the block frame, and we will + // never enter into this RecoverStateFrom(aLine) function. + // case first line of mBlock is clean : it is untouched by the incremental reflow. + // In other words, aLine is never equals to mBlock->mLines in this function. + // so mBlock->mAscent will remain unchanged. +#endif // Place floaters for this line into the space manager if (aLine->HasFloaters()) { @@ -1438,6 +1449,14 @@ nsBlockFrame::IsPercentageBase(PRBool& aBase) const ////////////////////////////////////////////////////////////////////// // Reflow methods +#ifdef MOZ_MATHML +inline nscoord +nsBlockFrame::GetAscent() const +{ + return mAscent; +} +#endif + static void CalculateContainingBlock(const nsHTMLReflowState& aReflowState, nscoord aFrameWidth, @@ -2259,6 +2278,11 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, autoHeight += borderPadding.bottom; // Apply min/max values +#ifdef MOZ_MATHML + // XXX Here in ComputeFinalSize() + // XXX What to do when min/max values are applied to the height? + // How do all this impact on the first line of the block? +#endif if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxHeight) { nscoord computedMaxHeight = aReflowState.mComputedMaxHeight + borderPadding.top + borderPadding.bottom; @@ -2281,8 +2305,22 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState, } } +#ifndef MOZ_MATHML aMetrics.ascent = aMetrics.height; aMetrics.descent = 0; +#else + if (mLines && mLines->mFirstChild && mLines->IsBlock()) { + // mAscent is not yet set because we didn't call VerticalAlignFrames() + // on mLines. So we need to fetch the ascent of the first child of mLines + nsBlockFrame* bf; + nsresult res = mLines->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&bf); + if (NS_SUCCEEDED(res) && bf) { + mAscent = bf->GetAscent(); + } + } + aMetrics.ascent = mAscent; + aMetrics.descent = aMetrics.height - aMetrics.ascent; +#endif if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) { // Store away the final value aMetrics.maxElementSize->width = maxWidth; @@ -4625,7 +4663,16 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, addedBullet = PR_TRUE; } nsSize maxElementSize; +#ifndef MOZ_MATHML aLineLayout.VerticalAlignFrames(aLine, maxElementSize); +#else + nscoord lineAscent; + aLineLayout.VerticalAlignFrames(aLine, maxElementSize, lineAscent); + // Our ascent is the ascent of our first line + if (aLine == mLines) { + mAscent = lineAscent; + } +#endif // See if we're shrink wrapping the width if (aState.GetFlag(BRS_SHRINKWRAPWIDTH)) { // When determining the line's width we also need to include any @@ -4696,6 +4743,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nscoord dy = -aState.mPrevBottomMargin; newY = aState.mY + dy; aLine->SlideBy(dy); +#ifdef MOZ_MATHML + // keep our ascent in sync + if (mLines == aLine) { + mAscent += dy; + } +#endif } // See if the line fit. If it doesn't we need to push it. Our first diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index 082925542c6..a4986c04c7b 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -1539,9 +1539,16 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent) #define VALIGN_TOP 1 #define VALIGN_BOTTOM 2 +#ifndef MOZ_MATHML void nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult) +#else +void +nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, + nsSize& aMaxElementSizeResult, + nscoord& aLineBoxAscent) +#endif { // Synthesize a PerFrameData for the block frame PerFrameData rootPFD; @@ -1680,6 +1687,9 @@ nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox, mFinalLineHeight = lineHeight; aMaxElementSizeResult.width = maxElementWidth; aMaxElementSizeResult.height = maxElementHeight; +#ifdef MOZ_MATHML + aLineBoxAscent = baselineY; +#endif // Undo root-span mFrame pointer to prevent brane damage later on... mRootSpan->mFrame = nsnull; diff --git a/mozilla/layout/html/base/src/nsLineLayout.h b/mozilla/layout/html/base/src/nsLineLayout.h index 01ee96fbffd..4a2e4c2b100 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.h +++ b/mozilla/layout/html/base/src/nsLineLayout.h @@ -117,8 +117,14 @@ public: PushFrame(aFrame); } +#ifndef MOZ_MATHML void VerticalAlignFrames(nsLineBox* aLineBox, nsSize& aMaxElementSizeResult); +#else + void VerticalAlignFrames(nsLineBox* aLineBox, + nsSize& aMaxElementSizeResult, + nscoord& aLineBoxAscent); +#endif PRBool TrimTrailingWhiteSpace();