Apply font size inflation to line heights. (Bug 627842, patch 11) r=roc

Since font size inflation applies to the text after style data
computation, we must separately apply this inflation to line heights.
This commit is contained in:
L. David Baron 2011-11-15 17:02:01 +13:00
parent 9523a6cd10
commit 17facb7829
9 changed files with 97 additions and 23 deletions

View File

@ -217,7 +217,8 @@ nsTextControlFrame::GetType() const
nsresult
nsTextControlFrame::CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
nsSize& aIntrinsicSize)
nsSize& aIntrinsicSize,
float aFontSizeInflation)
{
// Get leading and the Average/MaxAdvance char width
nscoord lineHeight = 0;
@ -226,12 +227,14 @@ nsTextControlFrame::CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
nsRefPtr<nsFontMetrics> fontMet;
nsresult rv =
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet),
aFontSizeInflation);
NS_ENSURE_SUCCESS(rv, rv);
aRenderingContext->SetFont(fontMet);
lineHeight =
nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT);
nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT,
aFontSizeInflation);
charWidth = fontMet->AveCharWidth();
charMaxAdvance = fontMet->MaxAdvance();
@ -498,8 +501,16 @@ nsTextControlFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
nsSize aMargin, nsSize aBorder,
nsSize aPadding, bool aShrinkWrap)
{
float inflation;
if (nsLayoutUtils::IsContainerForFontSizeInflation(this)) {
// FIXME: This won't turn out so well for the height; maybe disable
// inflation entirely in this case?
inflation = 1.0f;
} else {
inflation = nsLayoutUtils::FontSizeInflationFor(this, aCBSize.width);
}
nsSize autoSize;
nsresult rv = CalcIntrinsicSize(aRenderingContext, autoSize);
nsresult rv = CalcIntrinsicSize(aRenderingContext, autoSize, inflation);
if (NS_FAILED(rv)) {
// What now?
autoSize.SizeTo(0, 0);
@ -512,7 +523,8 @@ nsTextControlFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
aCBSize, aAvailableWidth,
aMargin, aBorder,
aPadding, aShrinkWrap);
NS_ASSERTION(ancestorAutoSize.width == autoSize.width,
// Disabled when there's inflation; see comment in GetPrefSize.
NS_ASSERTION(inflation != 1.0f || ancestorAutoSize.width == autoSize.width,
"Incorrect size computed by ComputeAutoSize?");
}
#endif
@ -553,7 +565,11 @@ nsTextControlFrame::GetPrefSize(nsBoxLayoutState& aState)
nsSize pref(0,0);
nsresult rv = CalcIntrinsicSize(aState.GetRenderingContext(), pref);
// FIXME: This inflation parameter isn't correct; we should fix it if
// we want font size inflation to work well in XUL. If we do, we can
// also re-enable the assertion in ComputeAutoSize when inflation is
// enabled.
nsresult rv = CalcIntrinsicSize(aState.GetRenderingContext(), pref, 1.0f);
NS_ENSURE_SUCCESS(rv, pref);
AddBorderAndPadding(pref);
@ -599,16 +615,37 @@ nsTextControlFrame::GetBoxAscent(nsBoxLayoutState& aState)
// Return the baseline of the first (nominal) row, with centering for
// single-line controls.
float inflation;
if (nsLayoutUtils::IsContainerForFontSizeInflation(this)) {
inflation =
nsLayoutUtils::FontSizeInflationFor(this, GetContentRect().width);
} else {
const nsHTMLReflowState *outerReflowState = aState.OuterReflowState();
NS_ASSERTION(outerReflowState || !mParent || mParent->IsBoxFrame() ||
!(mParent->GetStateBits() & NS_FRAME_IN_REFLOW),
"when a text control is reflowed by one of its ancestors "
"and its parent is non-XUL, we should have the outer "
"reflow state in the box layout state");
if (outerReflowState && outerReflowState->frame == this) {
inflation = nsLayoutUtils::FontSizeInflationFor(*outerReflowState);
} else {
inflation = nsLayoutUtils::FontSizeInflationInner(this,
nsLayoutUtils::InflationMinFontSizeFor(mParent));
}
}
// First calculate the ascent wrt the client rect
nsRect clientRect;
GetClientRect(clientRect);
nscoord lineHeight =
IsSingleLineTextControl() ? clientRect.height :
nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT);
nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT,
inflation);
nsRefPtr<nsFontMetrics> fontMet;
nsresult rv =
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet),
inflation);
NS_ENSURE_SUCCESS(rv, 0);
nscoord ascent = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight);

View File

@ -392,7 +392,8 @@ protected:
// etc. Just the size of our actual area for the text (and the scrollbars,
// for <textarea>).
nsresult CalcIntrinsicSize(nsRenderingContext* aRenderingContext,
nsSize& aIntrinsicSize);
nsSize& aIntrinsicSize,
float aFontSizeInflation);
nsresult ScrollSelectionIntoView();

View File

@ -565,7 +565,8 @@ nsBlockFrame::GetCaretBaseline() const
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
return nsLayoutUtils::GetCenteredFontBaseline(fm, nsHTMLReflowState::
CalcLineHeight(GetStyleContext(), contentRect.height)) +
CalcLineHeight(GetStyleContext(), contentRect.height,
nsLayoutUtils::FontSizeInflationFor(this))) +
bp.top;
}

View File

@ -2149,10 +2149,13 @@ GetNormalLineHeight(nsFontMetrics* aFontMetrics)
return normalLineHeight;
}
static nscoord
static inline nscoord
ComputeLineHeight(nsStyleContext* aStyleContext,
nscoord aBlockHeight)
nscoord aBlockHeight,
bool* aIsBlockHeight)
{
*aIsBlockHeight = false;
const nsStyleCoord& lhCoord = aStyleContext->GetStyleText()->mLineHeight;
if (lhCoord.GetUnit() == eStyleUnit_Coord)
@ -2172,8 +2175,10 @@ ComputeLineHeight(nsStyleContext* aStyleContext,
if (lhCoord.GetUnit() == eStyleUnit_Enumerated) {
NS_ASSERTION(lhCoord.GetIntValue() == NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT,
"bad line-height value");
if (aBlockHeight != NS_AUTOHEIGHT)
if (aBlockHeight != NS_AUTOHEIGHT) {
*aIsBlockHeight = true;
return aBlockHeight;
}
}
nsRefPtr<nsFontMetrics> fm;
@ -2189,19 +2194,27 @@ nsHTMLReflowState::CalcLineHeight() const
nsLayoutUtils::IsNonWrapperBlock(frame) ? mComputedHeight :
(mCBReflowState ? mCBReflowState->mComputedHeight : NS_AUTOHEIGHT);
return CalcLineHeight(frame->GetStyleContext(), blockHeight);
return CalcLineHeight(frame->GetStyleContext(), blockHeight,
nsLayoutUtils::FontSizeInflationFor(*this));
}
/* static */ nscoord
nsHTMLReflowState::CalcLineHeight(nsStyleContext* aStyleContext,
nscoord aBlockHeight)
nscoord aBlockHeight,
float aFontSizeInflation)
{
NS_PRECONDITION(aStyleContext, "Must have a style context");
nscoord lineHeight = ComputeLineHeight(aStyleContext, aBlockHeight);
bool isBlockHeight;
nscoord lineHeight =
ComputeLineHeight(aStyleContext, aBlockHeight, &isBlockHeight);
NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up");
if (aFontSizeInflation != 1.0f && !isBlockHeight) {
lineHeight = NSToCoordRound(lineHeight * aFontSizeInflation);
}
return lineHeight;
}

View File

@ -419,9 +419,14 @@ public:
* Only used with line-height:-moz-block-height.
* NS_AUTOHEIGHT results in a normal line-height for
* line-height:-moz-block-height.
* @param aFontSizeInflation The result of the appropriate
* nsLayoutUtils::FontSizeInflationFor call,
* or 1.0 if during intrinsic size
* calculation.
*/
static nscoord CalcLineHeight(nsStyleContext* aStyleContext,
nscoord aBlockHeight);
nscoord aBlockHeight,
float aFontSizeInflation);
void ComputeContainingBlockRectangle(nsPresContext* aPresContext,

View File

@ -120,6 +120,9 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext,
mTopEdge = 0;
mTrimmableWidth = 0;
mInflationMinFontSize =
nsLayoutUtils::InflationMinFontSizeFor(*aOuterReflowState);
// Instead of always pre-initializing the free-lists for frames and
// spans, we do it on demand so that situations that only use a few
// frames and spans won't waste a lot of time in unneeded
@ -1589,7 +1592,10 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd)
// Get the parent frame's font for all of the frames in this span
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(spanFrame, getter_AddRefs(fm));
float inflation =
nsLayoutUtils::FontSizeInflationInner(spanFrame, mInflationMinFontSize);
nsLayoutUtils::GetFontMetricsForFrame(spanFrame, getter_AddRefs(fm),
inflation);
mBlockReflowState->rendContext->SetFont(fm);
bool preMode = mStyleText->WhiteSpaceIsSignificant();
@ -1720,9 +1726,12 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd)
// 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.
float inflation =
nsLayoutUtils::FontSizeInflationInner(spanFrame, mInflationMinFontSize);
nscoord logicalHeight = nsHTMLReflowState::
CalcLineHeight(spanFrame->GetStyleContext(),
mBlockReflowState->ComputedHeight());
mBlockReflowState->ComputedHeight(),
inflation);
nscoord contentHeight = spanFramePFD->mBounds.height -
spanFramePFD->mBorderPadding.top - spanFramePFD->mBorderPadding.bottom;
@ -1959,8 +1968,11 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd)
if (verticalAlign.HasPercent()) {
// Percentages are like lengths, except treated as a percentage
// of the elements line-height value.
float inflation =
nsLayoutUtils::FontSizeInflationInner(frame, mInflationMinFontSize);
pctBasis = nsHTMLReflowState::CalcLineHeight(
frame->GetStyleContext(), mBlockReflowState->ComputedHeight());
frame->GetStyleContext(), mBlockReflowState->ComputedHeight(),
inflation);
}
nscoord offset =
nsRuleNode::ComputeCoordPercentCalc(verticalAlign, pctBasis);

View File

@ -550,6 +550,8 @@ protected:
nscoord mMaxTopBoxHeight;
nscoord mMaxBottomBoxHeight;
nscoord mInflationMinFontSize;
// Final computed line-height value after VerticalAlignFrames for
// the block has been called.
nscoord mFinalLineHeight;

View File

@ -4588,7 +4588,8 @@ ComputeDescentLimitForSelectionUnderline(nsPresContext* aPresContext,
{
gfxFloat app = aPresContext->AppUnitsPerDevPixel();
nscoord lineHeightApp =
nsHTMLReflowState::CalcLineHeight(aFrame->GetStyleContext(), NS_AUTOHEIGHT);
nsHTMLReflowState::CalcLineHeight(aFrame->GetStyleContext(), NS_AUTOHEIGHT,
aFrame->GetFontSizeInflation());
gfxFloat lineHeight = gfxFloat(lineHeightApp) / app;
if (lineHeight <= aFontMetrics.maxHeight) {
return aFontMetrics.maxDescent;

View File

@ -3413,8 +3413,10 @@ nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord)
}
}
// lie about font size inflation since we lie about font size (since
// the inflation only applies to text)
aCoord = nsHTMLReflowState::CalcLineHeight(mStyleContextHolder,
blockHeight);
blockHeight, 1.0f);
// CalcLineHeight uses font->mFont.size, but we want to use
// font->mSize as the font size. Adjust for that. Also adjust for