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
Родитель 1a154708dc
Коммит 9d83d9e503
8 изменённых файлов: 79 добавлений и 52 удалений

Просмотреть файл

@ -39,7 +39,6 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsIFrame.h"
#include "nsIFontMetrics.h" #include "nsIFontMetrics.h"
#include "nsIFormControlFrame.h" #include "nsIFormControlFrame.h"
#include "nsPresContext.h" #include "nsPresContext.h"
@ -1254,7 +1253,7 @@ static nscoord AddPercents(nsLayoutUtils::IntrinsicWidthType aType,
/* static */ PRBool /* static */ PRBool
nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle, nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle,
nsIRenderingContext* aRenderingContext, nsIRenderingContext* aRenderingContext,
nsIFrame* aFrame, nsStyleContext* aStyleContext,
nscoord& aResult) nscoord& aResult)
{ {
nsStyleUnit unit = aStyle.GetUnit(); nsStyleUnit unit = aStyle.GetUnit();
@ -1264,7 +1263,7 @@ nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle,
} }
if (eStyleUnit_Chars == unit) { if (eStyleUnit_Chars == unit) {
aResult = nsLayoutUtils::CharsToCoord(aStyle, aRenderingContext, aResult = nsLayoutUtils::CharsToCoord(aStyle, aRenderingContext,
aFrame->GetStyleContext()); aStyleContext);
return PR_TRUE; return PR_TRUE;
} }
return PR_FALSE; return PR_FALSE;

Просмотреть файл

@ -41,7 +41,6 @@
#ifndef nsLayoutUtils_h__ #ifndef nsLayoutUtils_h__
#define nsLayoutUtils_h__ #define nsLayoutUtils_h__
class nsIFrame;
class nsIFormControlFrame; class nsIFormControlFrame;
class nsPresContext; class nsPresContext;
class nsIContent; class nsIContent;
@ -58,6 +57,7 @@ class nsIFontMetrics;
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsStyleSet.h" #include "nsStyleSet.h"
#include "nsIView.h" #include "nsIView.h"
#include "nsIFrame.h"
class nsBlockFrame; class nsBlockFrame;
@ -547,6 +547,18 @@ public:
static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle,
nsIRenderingContext* aRenderingContext, nsIRenderingContext* aRenderingContext,
nsIFrame* aFrame, 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); nscoord& aResult);
/** /**
* Get the contribution of aFrame to its containing block's intrinsic * Get the contribution of aFrame to its containing block's intrinsic

Просмотреть файл

@ -2040,62 +2040,40 @@ GetNormalLineHeight(nsIFontMetrics* aFontMetrics)
// Need only one of aRenderingContext and aDeviceContext // Need only one of aRenderingContext and aDeviceContext
static nscoord static nscoord
ComputeLineHeight(nsIRenderingContext* aRenderingContext, ComputeLineHeight(nsIRenderingContext* aRenderingContext,
nsIDeviceContext* aDeviceContext,
nsStyleContext* aStyleContext) nsStyleContext* aStyleContext)
{ {
NS_PRECONDITION(aRenderingContext || aDeviceContext,
"Need to have a way of getting a device context");
nscoord lineHeight; nscoord lineHeight;
const nsStyleFont* font = aStyleContext->GetStyleFont();
const nsStyleCoord& lhCoord = aStyleContext->GetStyleText()->mLineHeight; const nsStyleCoord& lhCoord = aStyleContext->GetStyleText()->mLineHeight;
nsStyleUnit unit = lhCoord.GetUnit(); if (!nsLayoutUtils::GetAbsoluteCoord(lhCoord, aRenderingContext,
aStyleContext, lineHeight)) {
if (unit == eStyleUnit_Coord) { const nsStyleFont* font = aStyleContext->GetStyleFont();
// For length values just use the pre-computed value if (lhCoord.GetUnit() == eStyleUnit_Factor) {
lineHeight = lhCoord.GetCoordValue(); // For factor units the computed value of the line-height property
} else if (unit == eStyleUnit_Factor) { // is found by multiplying the factor by the font's computed size
// For factor units the computed value of the line-height property // (adjusted for min-size prefs and text zoom).
// is found by multiplying the factor by the font's computed size float factor = lhCoord.GetFactorValue();
// (adjusted for min-size prefs and text zoom). lineHeight = NSToCoordRound(factor * font->mFont.size);
float factor = lhCoord.GetFactorValue(); } else {
lineHeight = NSToCoordRound(factor * font->mFont.size); NS_ASSERTION(eStyleUnit_Normal == lhCoord.GetUnit(), "bad unit");
} else { nsCOMPtr<nsIFontMetrics> fm;
NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit"); nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
nsCOMPtr<nsIFontMetrics> fm; getter_AddRefs(fm));
nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext, lineHeight = GetNormalLineHeight(fm);
getter_AddRefs(fm)); }
lineHeight = GetNormalLineHeight(fm);
} }
return lineHeight; return lineHeight;
} }
nscoord nscoord
nsHTMLReflowState::CalcLineHeight(nsIRenderingContext* aRenderingContext, nsHTMLReflowState::CalcLineHeight(nsIRenderingContext* aRenderingContext,
nsIFrame* aFrame) nsStyleContext* aStyleContext)
{
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)
{ {
NS_PRECONDITION(aRenderingContext, "Must have a rendering context");
NS_PRECONDITION(aStyleContext, "Must have a style context"); NS_PRECONDITION(aStyleContext, "Must have a style context");
NS_PRECONDITION(aDeviceContext, "Must have a device context");
nscoord lineHeight = ComputeLineHeight(nsnull, aDeviceContext, nscoord lineHeight = ComputeLineHeight(aRenderingContext, aStyleContext);
aStyleContext);
NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up"); NS_ASSERTION(lineHeight >= 0, "ComputeLineHeight screwed up");

Просмотреть файл

@ -419,12 +419,16 @@ public:
* value will be >= 0. * value will be >= 0.
*/ */
static nscoord CalcLineHeight(nsIRenderingContext* aRenderingContext, 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, static nscoord CalcLineHeight(nsIRenderingContext* aRenderingContext,
nsIDeviceContext* aDeviceContext); nsStyleContext* aStyleContext);
void ComputeContainingBlockRectangle(nsPresContext* aPresContext, void ComputeContainingBlockRectangle(nsPresContext* aPresContext,

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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-1a.html 390318-1-ref.html
== 390318-1b.html 390318-1-ref.html == 390318-1b.html 390318-1-ref.html
== 391140-1.html 391140-1-ref.html == 391140-1.html 391140-1-ref.html
== 391909-1.html 391909-1-ref.html
== 391994-1.html 391994-1-ref.html == 391994-1.html 391994-1-ref.html

Просмотреть файл

@ -2765,9 +2765,20 @@ nsComputedDOMStyle::GetPaddingWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue)
PRBool PRBool
nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord) nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord)
{ {
aCoord = nsHTMLReflowState::CalcLineHeight(mStyleContextHolder, // Get a rendering context
mPresShell->GetPresContext()-> nsCOMPtr<nsIRenderingContext> cx;
DeviceContext()); 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 // CalcLineHeight uses font->mFont.size, but we want to use
// font->mSize as the font size. Adjust for that. Also adjust for // font->mSize as the font size. Adjust for that. Also adjust for
// the text zoom, if any. // the text zoom, if any.