From f7abcf04bcc388721dccb8c1627af9ba5a835706 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Wed, 23 Nov 2011 18:48:23 -0800 Subject: [PATCH] Make other users of font metrics (other than MathML and XUL) honor font size inflation. (Bug 627842, patch 15) r=roc This does not address users of font metrics in layout/mathml/ (for text size and alignment issues) or in layout/xul (for text size and sizing of listbox and tree widgets): see all the callers of GetFontMetricsFor* in those directories. --- content/events/src/nsEventStateManager.cpp | 3 +- layout/base/nsCaret.cpp | 3 +- layout/forms/nsListControlFrame.cpp | 38 +++++++++++++++------- layout/forms/nsListControlFrame.h | 13 +++++--- layout/forms/nsProgressFrame.cpp | 5 ++- layout/forms/nsSelectsAreaFrame.cpp | 2 +- layout/generic/TextOverflow.cpp | 6 ++-- layout/generic/nsBRFrame.cpp | 24 ++++---------- layout/generic/nsBlockFrame.cpp | 6 ++-- layout/generic/nsGfxScrollFrame.cpp | 3 +- layout/generic/nsImageFrame.cpp | 3 +- layout/generic/nsTextFrameThebes.cpp | 3 +- 12 files changed, 66 insertions(+), 43 deletions(-) diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 80cfc2e4652..91af42783c8 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -2544,7 +2544,8 @@ GetScrollableLineHeight(nsIFrame* aTargetFrame) // Fall back to the font height of the target frame. nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(aTargetFrame, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(aTargetFrame)); NS_ASSERTION(fm, "FontMetrics is null!"); if (fm) return fm->MaxHeight(); diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index c64466982bc..0d7f799ba86 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -350,7 +350,8 @@ nsCaret::GetGeometryForFrame(nsIFrame* aFrame, nscoord baseline = frame->GetCaretBaseline(); nscoord ascent = 0, descent = 0; nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(aFrame)); NS_ASSERTION(fm, "We should be able to get the font metrics"); if (fm) { ascent = fm->MaxAscent(); diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 4341d91cc0d..2db13423c1f 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -257,9 +257,10 @@ void nsListControlFrame::PaintFocus(nsRenderingContext& aRC, nsPoint aPt) // get it into our coordinates fRect.MoveBy(childframe->GetParent()->GetOffsetTo(this)); } else { + float inflation = nsLayoutUtils::FontSizeInflationFor(this); fRect.x = fRect.y = 0; fRect.width = GetScrollPortRect().width; - fRect.height = CalcFallbackRowHeight(); + fRect.height = CalcFallbackRowHeight(inflation); fRect.MoveBy(containerFrame->GetOffsetTo(this)); } fRect += aPt; @@ -283,7 +284,7 @@ void nsListControlFrame::PaintFocus(nsRenderingContext& aRC, nsPoint aPt) } void -nsListControlFrame::InvalidateFocus() +nsListControlFrame::InvalidateFocus(const nsHTMLReflowState *aReflowState) { if (mFocused != this) return; @@ -293,8 +294,16 @@ nsListControlFrame::InvalidateFocus() // Invalidating from the containerFrame because that's where our focus // is drawn. // The origin of the scrollport is the origin of containerFrame. + float inflation; + if (aReflowState) { + NS_ABORT_IF_FALSE(aReflowState->frame == this, "wrong reflow state"); + inflation = nsLayoutUtils::FontSizeInflationFor(*aReflowState); + } else { + inflation = nsLayoutUtils::FontSizeInflationFor(this); + } nsRect invalidateArea = containerFrame->GetVisualOverflowRect(); - nsRect emptyFallbackArea(0, 0, GetScrollPortRect().width, CalcFallbackRowHeight()); + nsRect emptyFallbackArea(0, 0, GetScrollPortRect().width, + CalcFallbackRowHeight(inflation)); invalidateArea.UnionRect(invalidateArea, emptyFallbackArea); containerFrame->Invalidate(invalidateArea); } @@ -365,8 +374,11 @@ GetNumberOfOptionsRecursive(nsIContent* aContent) // Main Reflow for ListBox/Dropdown //----------------------------------------------------------------- +// Note that it doesn't much matter *which* reflow state aReflowState +// is (as long as it's in the right block); we intentionally pass +// whatever reflow state is most convenient. nscoord -nsListControlFrame::CalcHeightOfARow() +nsListControlFrame::CalcHeightOfARow(const nsHTMLReflowState& aReflowState) { // Calculate the height of a single row in the listbox or dropdown list by // using the tallest thing in the subtree, since there may be option groups @@ -377,7 +389,9 @@ nsListControlFrame::CalcHeightOfARow() // Check to see if we have zero items (and optimize by checking // heightOfARow first) if (heightOfARow == 0 && GetNumberOfOptions() == 0) { - heightOfARow = CalcFallbackRowHeight(); + nscoord minFontSize = nsLayoutUtils::InflationMinFontSizeFor(aReflowState); + float inflation = nsLayoutUtils::FontSizeInflationInner(this, minFontSize); + heightOfARow = CalcFallbackRowHeight(inflation); } return heightOfARow; @@ -500,7 +514,7 @@ nsListControlFrame::Reflow(nsPresContext* aPresContext, // already set mNumDisplayRows in CalcIntrinsicHeight. Also note that we // can't use HeightOfARow() here because that just uses a cached value // that we didn't compute. - nscoord rowHeight = CalcHeightOfARow(); + nscoord rowHeight = CalcHeightOfARow(aReflowState); if (rowHeight == 0) { // Just pick something mNumDisplayRows = 1; @@ -1167,7 +1181,8 @@ nsListControlFrame::OnContentReset() } void -nsListControlFrame::ResetList(bool aAllowScrolling) +nsListControlFrame::ResetList(bool aAllowScrolling, + const nsHTMLReflowState *aReflowState) { // if all the frames aren't here // don't bother reseting @@ -1191,7 +1206,7 @@ nsListControlFrame::ResetList(bool aAllowScrolling) mStartSelectionIndex = kNothingSelected; mEndSelectionIndex = kNothingSelected; - InvalidateFocus(); + InvalidateFocus(aReflowState); // Combobox will redisplay itself with the OnOptionSelected event } @@ -1744,7 +1759,7 @@ nsListControlFrame::DidReflow(nsPresContext* aPresContext, // The idea is that we want scroll history restoration to trump ResetList // scrolling to the selected element, when the ResetList was probably only // caused by content loading normally. - ResetList(!DidHistoryRestore() || mPostChildrenLoadedReset); + ResetList(!DidHistoryRestore() || mPostChildrenLoadedReset, aReflowState); } mHasPendingInterruptAtStartOfReflow = false; @@ -1813,12 +1828,13 @@ nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent) } nscoord -nsListControlFrame::CalcFallbackRowHeight() +nsListControlFrame::CalcFallbackRowHeight(float aFontSizeInflation) { nscoord rowHeight = 0; nsRefPtr fontMet; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet), + aFontSizeInflation); if (fontMet) { rowHeight = fontMet->MaxHeight(); } diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index b86fd290e0c..245eabfc360 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -239,14 +239,16 @@ public: * that PaintFocus will or could have painted --- basically the whole * GetOptionsContainer, plus some extra stuff if there are no options. This * must be called every time mEndSelectionIndex changes. + * + * Pass non-null aReflowState if during reflow. */ - void InvalidateFocus(); + void InvalidateFocus(const nsHTMLReflowState* aReflowState = nsnull); /** * Function to calculate the height a row, for use with the "size" attribute. * Can't be const because GetNumberOfOptions() isn't const. */ - nscoord CalcHeightOfARow(); + nscoord CalcHeightOfARow(const nsHTMLReflowState& aReflowState); /** * Function to ask whether we're currently in what might be the @@ -332,8 +334,11 @@ protected: /** * Resets the select back to it's original default values; * those values as determined by the original HTML + * + * Pass non-null aReflowState if during reflow. */ - virtual void ResetList(bool aAllowScrolling); + virtual void ResetList(bool aAllowScrolling, + const nsHTMLReflowState* aReflowState = nsnull); nsListControlFrame(nsIPresShell* aShell, nsIDocument* aDocument, nsStyleContext* aContext); virtual ~nsListControlFrame(); @@ -373,7 +378,7 @@ protected: bool IsLeftButton(nsIDOMEvent* aMouseEvent); // guess at a row height based on our own style. - nscoord CalcFallbackRowHeight(); + nscoord CalcFallbackRowHeight(float aFontSizeInflation); // CalcIntrinsicHeight computes our intrinsic height (taking the "size" // attribute into account). This should only be called in non-dropdown mode. diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index 8a83b19446e..fefa6095ca3 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -262,9 +262,12 @@ nsProgressFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext, nsSize aMargin, nsSize aBorder, nsSize aPadding, bool aShrinkWrap) { + float inflation = + nsLayoutUtils::FontSizeInflationFor(this, aCBSize.width); nsRefPtr fontMet; NS_ENSURE_SUCCESS(nsLayoutUtils::GetFontMetricsForFrame(this, - getter_AddRefs(fontMet)), + getter_AddRefs(fontMet), + inflation), nsSize(0, 0)); nsSize autoSize; diff --git a/layout/forms/nsSelectsAreaFrame.cpp b/layout/forms/nsSelectsAreaFrame.cpp index 10506d92ce7..00a6f706a4b 100644 --- a/layout/forms/nsSelectsAreaFrame.cpp +++ b/layout/forms/nsSelectsAreaFrame.cpp @@ -234,7 +234,7 @@ nsSelectsAreaFrame::Reflow(nsPresContext* aPresContext, // Check whether we need to suppress scrolbar updates. We want to do that if // we're in a possible first pass and our height of a row has changed. if (list->MightNeedSecondPass()) { - nscoord newHeightOfARow = list->CalcHeightOfARow(); + nscoord newHeightOfARow = list->CalcHeightOfARow(aReflowState); // We'll need a second pass if our height of a row changed. For // comboboxes, we'll also need it if our height changed. If we're going // to do a second pass, suppress scrollbar updates for this pass. diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 8ed733c289e..55fd9515820 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -244,7 +244,8 @@ nsDisplayTextOverflowMarker::PaintTextToContext(nsRenderingContext* aCtx, nsPoint aOffsetFromRect) { nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(mFrame)); aCtx->SetFont(fm); gfxFloat y = nsLayoutUtils::GetSnappedBaselineY(mFrame, aCtx->ThebesContext(), mRect.y, mAscent); @@ -657,7 +658,8 @@ TextOverflow::Marker::SetupString(nsIFrame* aFrame) nsRefPtr rc = aFrame->PresContext()->PresShell()->GetReferenceRenderingContext(); nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(aFrame)); rc->SetFont(fm); mMarkerString = mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS ? diff --git a/layout/generic/nsBRFrame.cpp b/layout/generic/nsBRFrame.cpp index 79f7cd529c8..a4230997c80 100644 --- a/layout/generic/nsBRFrame.cpp +++ b/layout/generic/nsBRFrame.cpp @@ -57,8 +57,6 @@ #include "nsFrameSelection.h" //END INCLUDES FOR SELECTION -#define BR_USING_CENTERED_FONT_BASELINE NS_FRAME_STATE_BIT(63) - class BRFrame : public nsFrame { public: NS_DECL_FRAMEARENA_HELPERS @@ -99,6 +97,8 @@ public: protected: BRFrame(nsStyleContext* aContext) : nsFrame(aContext) {} virtual ~BRFrame(); + + nscoord mAscent; }; nsIFrame* @@ -126,7 +126,6 @@ BRFrame::Reflow(nsPresContext* aPresContext, // However, it's not always 0. See below. aMetrics.width = 0; aMetrics.ascent = 0; - RemoveStateBits(BR_USING_CENTERED_FONT_BASELINE); // Only when the BR is operating in a line-layout situation will it // behave like a BR. @@ -151,14 +150,14 @@ BRFrame::Reflow(nsPresContext* aPresContext, // normal inline frame. That line-height is used is important // here for cases where the line-height is less than 1. nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(aReflowState)); aReflowState.rendContext->SetFont(fm); // FIXME: maybe not needed? if (fm) { nscoord logicalHeight = aReflowState.CalcLineHeight(); aMetrics.height = logicalHeight; aMetrics.ascent = nsLayoutUtils::GetCenteredFontBaseline(fm, logicalHeight); - AddStateBits(BR_USING_CENTERED_FONT_BASELINE); } else { aMetrics.ascent = aMetrics.height = 0; @@ -189,6 +188,8 @@ BRFrame::Reflow(nsPresContext* aPresContext, aMetrics.SetOverflowAreasToDesiredBounds(); + mAscent = aMetrics.ascent; + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics); return NS_OK; } @@ -232,18 +233,7 @@ BRFrame::GetType() const nscoord BRFrame::GetBaseline() const { - nscoord ascent = 0; - nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); - if (fm) { - nscoord logicalHeight = GetRect().height; - if (GetStateBits() & BR_USING_CENTERED_FONT_BASELINE) { - ascent = nsLayoutUtils::GetCenteredFontBaseline(fm, logicalHeight); - } else { - ascent = fm->MaxAscent() + GetUsedBorderAndPadding().top; - } - } - return NS_MIN(mRect.height, ascent); + return mAscent; } nsIFrame::ContentOffsets BRFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 645ba1c6144..a6a483c959e 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -563,7 +563,8 @@ nsBlockFrame::GetCaretBaseline() const } } nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(this)); return nsLayoutUtils::GetCenteredFontBaseline(fm, nsHTMLReflowState:: CalcLineHeight(GetStyleContext(), contentRect.height, nsLayoutUtils::FontSizeInflationFor(this))) + @@ -2333,7 +2334,8 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState) } nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(aState.mReflowState)); aState.mReflowState.rendContext->SetFont(fm); // FIXME: needed? nscoord minAscent = diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 49fd06e5a6f..244340718c1 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -2199,7 +2199,8 @@ nsSize nsGfxScrollFrameInner::GetLineScrollAmount() const { nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(mOuter, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(mOuter, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(mOuter)); NS_ASSERTION(fm, "FontMetrics is null, assuming fontHeight == 1 appunit"); nscoord fontHeight = 1; if (fm) { diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 7aca719e29f..09482e114e9 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -986,7 +986,8 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext, // Set font and color aRenderingContext.SetColor(GetStyleColor()->mColor); nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), + nsLayoutUtils::FontSizeInflationFor(this)); aRenderingContext.SetFont(fm); // Format the text to display within the formatting rect diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 17d9270bc60..683e9d68774 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -5742,7 +5742,8 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext, nsRect givenRect = aRect; nsRefPtr fm; - nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm)); + nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm), + GetFontSizeInflation()); gfxFontGroup* fontGroup = fm->GetThebesFontGroup(); gfxFont* firstFont = fontGroup->GetFontAt(0); if (!firstFont)