From 9d83d9e503e0fdd8c5ef369867c974847b67c091 Mon Sep 17 00:00:00 2001 From: "bzbarsky@mit.edu" Date: Fri, 24 Aug 2007 15:20:24 -0700 Subject: [PATCH] Make line-height specified in ch units work. Bug 391909, r+sr+a+dbaron --- layout/base/nsLayoutUtils.cpp | 5 +-- layout/base/nsLayoutUtils.h | 14 +++++- layout/generic/nsHTMLReflowState.cpp | 60 ++++++++------------------ layout/generic/nsHTMLReflowState.h | 12 ++++-- layout/reftests/bugs/391909-1-ref.html | 14 ++++++ layout/reftests/bugs/391909-1.html | 8 ++++ layout/reftests/bugs/reftest.list | 1 + layout/style/nsComputedDOMStyle.cpp | 17 ++++++-- 8 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 layout/reftests/bugs/391909-1-ref.html create mode 100644 layout/reftests/bugs/391909-1.html diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 9f6ac350100..4755ca994cf 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -39,7 +39,6 @@ * ***** END LICENSE BLOCK ***** */ #include "nsLayoutUtils.h" -#include "nsIFrame.h" #include "nsIFontMetrics.h" #include "nsIFormControlFrame.h" #include "nsPresContext.h" @@ -1254,7 +1253,7 @@ static nscoord AddPercents(nsLayoutUtils::IntrinsicWidthType aType, /* static */ PRBool nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle, nsIRenderingContext* aRenderingContext, - nsIFrame* aFrame, + nsStyleContext* aStyleContext, nscoord& aResult) { nsStyleUnit unit = aStyle.GetUnit(); @@ -1264,7 +1263,7 @@ nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle, } if (eStyleUnit_Chars == unit) { aResult = nsLayoutUtils::CharsToCoord(aStyle, aRenderingContext, - aFrame->GetStyleContext()); + aStyleContext); return PR_TRUE; } return PR_FALSE; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 66916b10ab1..8209bc9dfd4 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -41,7 +41,6 @@ #ifndef nsLayoutUtils_h__ #define nsLayoutUtils_h__ -class nsIFrame; class nsIFormControlFrame; class nsPresContext; class nsIContent; @@ -58,6 +57,7 @@ class nsIFontMetrics; #include "nsAutoPtr.h" #include "nsStyleSet.h" #include "nsIView.h" +#include "nsIFrame.h" class nsBlockFrame; @@ -547,6 +547,18 @@ public: static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, nsIRenderingContext* aRenderingContext, nsIFrame* aFrame, + nscoord& aResult) + { + return GetAbsoluteCoord(aStyle, aRenderingContext, + aFrame->GetStyleContext(), aResult); + } + + /** + * Same as above but doesn't need a frame + */ + static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, + nsIRenderingContext* aRenderingContext, + nsStyleContext* aStyleContext, nscoord& aResult); /** * Get the contribution of aFrame to its containing block's intrinsic diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index a439acf7210..d97acf487de 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -2040,62 +2040,40 @@ GetNormalLineHeight(nsIFontMetrics* aFontMetrics) // Need only one of aRenderingContext and aDeviceContext static nscoord ComputeLineHeight(nsIRenderingContext* aRenderingContext, - nsIDeviceContext* aDeviceContext, nsStyleContext* aStyleContext) { - NS_PRECONDITION(aRenderingContext || aDeviceContext, - "Need to have a way of getting a device context"); - nscoord lineHeight; - const nsStyleFont* font = aStyleContext->GetStyleFont(); const nsStyleCoord& lhCoord = aStyleContext->GetStyleText()->mLineHeight; - nsStyleUnit unit = lhCoord.GetUnit(); - - if (unit == eStyleUnit_Coord) { - // For length values just use the pre-computed value - lineHeight = lhCoord.GetCoordValue(); - } else if (unit == eStyleUnit_Factor) { - // For factor units the computed value of the line-height property - // is found by multiplying the factor by the font's computed size - // (adjusted for min-size prefs and text zoom). - float factor = lhCoord.GetFactorValue(); - lineHeight = NSToCoordRound(factor * font->mFont.size); - } else { - NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit"); - nsCOMPtr fm; - nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext, - getter_AddRefs(fm)); - lineHeight = GetNormalLineHeight(fm); + if (!nsLayoutUtils::GetAbsoluteCoord(lhCoord, aRenderingContext, + aStyleContext, lineHeight)) { + const nsStyleFont* font = aStyleContext->GetStyleFont(); + if (lhCoord.GetUnit() == eStyleUnit_Factor) { + // For factor units the computed value of the line-height property + // is found by multiplying the factor by the font's computed size + // (adjusted for min-size prefs and text zoom). + float factor = lhCoord.GetFactorValue(); + lineHeight = NSToCoordRound(factor * font->mFont.size); + } else { + NS_ASSERTION(eStyleUnit_Normal == lhCoord.GetUnit(), "bad unit"); + nsCOMPtr fm; + nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext, + getter_AddRefs(fm)); + lineHeight = GetNormalLineHeight(fm); + } } return lineHeight; } nscoord nsHTMLReflowState::CalcLineHeight(nsIRenderingContext* aRenderingContext, - nsIFrame* aFrame) -{ - NS_ASSERTION(aFrame && aFrame->GetStyleContext(), - "Bogus data passed in to CalcLineHeight"); - - nscoord lineHeight = ComputeLineHeight(aRenderingContext, nsnull, - aFrame->GetStyleContext()); - - NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up"); - - return lineHeight; -} - -nscoord -nsHTMLReflowState::CalcLineHeight(nsStyleContext* aStyleContext, - nsIDeviceContext* aDeviceContext) + nsStyleContext* aStyleContext) { + NS_PRECONDITION(aRenderingContext, "Must have a rendering context"); NS_PRECONDITION(aStyleContext, "Must have a style context"); - NS_PRECONDITION(aDeviceContext, "Must have a device context"); - nscoord lineHeight = ComputeLineHeight(nsnull, aDeviceContext, - aStyleContext); + nscoord lineHeight = ComputeLineHeight(aRenderingContext, aStyleContext); NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up"); diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index a6a837f8f11..b216f2ae171 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -419,12 +419,16 @@ public: * value will be >= 0. */ static nscoord CalcLineHeight(nsIRenderingContext* aRenderingContext, - nsIFrame* aFrame); + nsIFrame* aFrame) + { + return CalcLineHeight(aRenderingContext, aFrame->GetStyleContext()); + } + /** - * Same as above, but doesn't need quite as much info. + * Same as above, but doesn't need a frame. */ - static nscoord CalcLineHeight(nsStyleContext* aStyleContext, - nsIDeviceContext* aDeviceContext); + static nscoord CalcLineHeight(nsIRenderingContext* aRenderingContext, + nsStyleContext* aStyleContext); void ComputeContainingBlockRectangle(nsPresContext* aPresContext, diff --git a/layout/reftests/bugs/391909-1-ref.html b/layout/reftests/bugs/391909-1-ref.html new file mode 100644 index 00000000000..cb236ec98e9 --- /dev/null +++ b/layout/reftests/bugs/391909-1-ref.html @@ -0,0 +1,14 @@ + + + +
+
+ This is a test +
+ + + diff --git a/layout/reftests/bugs/391909-1.html b/layout/reftests/bugs/391909-1.html new file mode 100644 index 00000000000..34b2d069a02 --- /dev/null +++ b/layout/reftests/bugs/391909-1.html @@ -0,0 +1,8 @@ + + + +
+This is a test +
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index d674c20833a..893c76397e1 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -365,4 +365,5 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 379316-2.html 379316-2-ref.html # bug == 390318-1a.html 390318-1-ref.html == 390318-1b.html 390318-1-ref.html == 391140-1.html 391140-1-ref.html +== 391909-1.html 391909-1-ref.html == 391994-1.html 391994-1-ref.html diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 0135a001e40..5fca84b3e6a 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2765,9 +2765,20 @@ nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue) PRBool nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord) { - aCoord = nsHTMLReflowState::CalcLineHeight(mStyleContextHolder, - mPresShell->GetPresContext()-> - DeviceContext()); + // Get a rendering context + nsCOMPtr cx; + nsIFrame* frame = mPresShell->FrameManager()->GetRootFrame(); + if (frame) { + mPresShell->CreateRenderingContext(frame, getter_AddRefs(cx)); + } + if (!cx) { + // Give up + aCoord = 0; + return PR_FALSE; + } + + aCoord = nsHTMLReflowState::CalcLineHeight(cx, mStyleContextHolder); + // CalcLineHeight uses font->mFont.size, but we want to use // font->mSize as the font size. Adjust for that. Also adjust for // the text zoom, if any.