Make line-height specified in ch units work. Bug 391909, r+sr+a+dbaron

This commit is contained in:
bzbarsky@mit.edu 2007-08-24 15:20:24 -07:00
parent d35aa3a819
commit 0aa9489e17
8 changed files with 79 additions and 52 deletions

View File

@ -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;

View File

@ -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

View File

@ -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) {
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 == unit, "bad unit");
NS_ASSERTION(eStyleUnit_Normal == lhCoord.GetUnit(), "bad unit");
nsCOMPtr<nsIFontMetrics> 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");

View File

@ -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,

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<body>
<div id="source" style="width: 3ch"></div>
<div id="target" style="width: 0">
This is a test
</div>
<script>
document.getElementById("target").style.lineHeight =
document.defaultView
.getComputedStyle(document.getElementById("source"), "").width;
</script>
</body>
</html>

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<body>
<div style="line-height: 3ch; width: 0">
This is a test
</div>
</body>
</html>

View File

@ -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

View File

@ -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<nsIRenderingContext> 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.