Reworked nsHTMLReflowState::CalcLineHeight (bug 6865)

This commit is contained in:
kipp%netscape.com 1999-09-09 21:03:27 +00:00
Родитель 056b8e9197
Коммит e5499ef843
2 изменённых файлов: 204 добавлений и 140 удалений

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

@ -27,6 +27,7 @@
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#ifdef NS_DEBUG #ifdef NS_DEBUG
#undef NOISY_VERTICAL_ALIGN #undef NOISY_VERTICAL_ALIGN
@ -1334,81 +1335,112 @@ nsHTMLReflowState::CalculateTableSideMargins(const nsHTMLReflowState* cbrs,
} }
#endif #endif
nscoord static nsIStyleContext*
nsHTMLReflowState::CalcLineHeight(nsIPresContext& aPresContext, GetNonInheritedLineHeightStyleContext(nsIStyleContext* aStyleContext)
nsIFrame* aFrame)
{ {
nscoord lineHeight = -1; nsCOMPtr<nsIStyleContext> parentSC;
nsIStyleContext* sc; parentSC = getter_AddRefs(aStyleContext->GetParent());
aFrame->GetStyleContext(&sc); if (parentSC) {
const nsStyleFont* elementFont = nsnull; const nsStyleText* text = (const nsStyleText*)
if (nsnull != sc) { parentSC->GetStyleData(eStyleStruct_Text);
elementFont = (const nsStyleFont*)sc->GetStyleData(eStyleStruct_Font); if (eStyleUnit_Inherit == text->mLineHeight.GetUnit()) {
for (;;) { return GetNonInheritedLineHeightStyleContext(parentSC);
const nsStyleText* text = (const nsStyleText*) }
sc->GetStyleData(eStyleStruct_Text); }
if (nsnull != text) { return parentSC;
nsStyleUnit unit = text->mLineHeight.GetUnit(); }
if (eStyleUnit_Normal == unit) {
// Normal value static nscoord
#ifdef NOISY_VERTICAL_ALIGN ComputeLineHeight(nsIRenderingContext* aRenderingContext,
printf(" line-height: normal\n"); nsIStyleContext* aStyleContext)
#endif {
break; nscoord lineHeight = 0;
} else if (eStyleUnit_Factor == unit) {
// CSS2 spec says that the number is inherited, not the const nsStyleText* text = (const nsStyleText*)
// computed value. Therefore use the font size of the aStyleContext->GetStyleData(eStyleStruct_Text);
// element times the inherited number. const nsStyleFont* font = (const nsStyleFont*)
nscoord size = elementFont->mFont.size; aStyleContext->GetStyleData(eStyleStruct_Font);
lineHeight = nscoord(size * text->mLineHeight.GetFactorValue());
if (lineHeight < 0) { nsStyleUnit unit = text->mLineHeight.GetUnit();
lineHeight = -1; if (eStyleUnit_Inherit == unit) {
} // Inherit parents line-height value
#ifdef NOISY_VERTICAL_ALIGN nsCOMPtr<nsIStyleContext> parentSC =
printf(" line-height: factor=%g result=%d\n", getter_AddRefs(GetNonInheritedLineHeightStyleContext(aStyleContext));
text->mLineHeight.GetFactorValue(), lineHeight); if (parentSC) {
#endif text = (const nsStyleText*) parentSC->GetStyleData(eStyleStruct_Text);
break; unit = text->mLineHeight.GetUnit();
} if (eStyleUnit_Percent == unit) {
else if (eStyleUnit_Coord == unit) { // For percent, we inherit the computed value so updated the
lineHeight = text->mLineHeight.GetCoordValue(); // font to use the parent's font not our font.
if (lineHeight < 0) { font = (const nsStyleFont*) parentSC->GetStyleData(eStyleStruct_Font);
lineHeight = -1;
}
break;
}
else if (eStyleUnit_Percent == unit) {
// XXX This could arguably be the font-metrics actual height
// instead since the spec says use the computed height.
const nsStyleFont* font = (const nsStyleFont*)
sc->GetStyleData(eStyleStruct_Font);
nscoord size = font->mFont.size;
lineHeight = nscoord(size * text->mLineHeight.GetPercentValue());
if (lineHeight < 0) {
lineHeight = -1;
}
break;
}
else if (eStyleUnit_Inherit == unit) {
nsIStyleContext* parentSC;
parentSC = sc->GetParent();
if (nsnull == parentSC) {
// Note: Break before releasing to avoid double-releasing sc
break;
}
NS_RELEASE(sc);
sc = parentSC;
}
else {
// other units are not part of the spec so don't bother
// looping
break;
}
} }
} }
NS_RELEASE(sc);
} }
if (eStyleUnit_Coord == unit) {
// For length values just use the pre-computed value
lineHeight = text->mLineHeight.GetCoordValue();
}
else {
// For "normal", factor or percentage units the computed value of
// the line-height property is found by multiplying the factor by
// the font's <b>actual</b> height. For "normal" we use a factor
// value of "1.0".
float factor = 1.0f;
if (eStyleUnit_Factor == unit) {
factor = text->mLineHeight.GetFactorValue();
}
else if (eStyleUnit_Percent == unit) {
factor = text->mLineHeight.GetPercentValue();
}
aRenderingContext->SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext->GetFontMetrics(*getter_AddRefs(fm));
if (fm) {
fm->GetHeight(lineHeight);
}
#ifdef DEBUG_kipp
// Note: we normally use the actual font height for computing the
// line-height raw value from the style context. On systems where
// they disagree the actual font height is more appropriate. This
// little hack lets us override that behavior to allow for more
// precise layout in the face of imprecise fonts.
static PRBool useComputedHeight = PR_FALSE;
#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
static PRBool firstTime = 1;
if (firstTime) {
if (getenv("GECKO_USE_COMPUTED_HEIGHT")) {
useComputedHeight = PR_TRUE;
}
firstTime = 0;
}
#endif
if (useComputedHeight) {
lineHeight = font->mFont.size;
}
#endif
lineHeight = NSToCoordRound(factor * lineHeight);
}
return lineHeight;
}
nscoord
nsHTMLReflowState::CalcLineHeight(nsIPresContext& aPresContext,
nsIRenderingContext* aRenderingContext,
nsIFrame* aFrame)
{
nscoord lineHeight = 0;
nsCOMPtr<nsIStyleContext> sc;
aFrame->GetStyleContext(getter_AddRefs(sc));
if (sc) {
lineHeight = ComputeLineHeight(aRenderingContext, sc);
}
if (lineHeight < 0) {
lineHeight = 0;
}
return lineHeight; return lineHeight;
} }

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

@ -27,6 +27,7 @@
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsLayoutAtoms.h" #include "nsLayoutAtoms.h"
#include "nsIRenderingContext.h" #include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#ifdef NS_DEBUG #ifdef NS_DEBUG
#undef NOISY_VERTICAL_ALIGN #undef NOISY_VERTICAL_ALIGN
@ -1334,81 +1335,112 @@ nsHTMLReflowState::CalculateTableSideMargins(const nsHTMLReflowState* cbrs,
} }
#endif #endif
nscoord static nsIStyleContext*
nsHTMLReflowState::CalcLineHeight(nsIPresContext& aPresContext, GetNonInheritedLineHeightStyleContext(nsIStyleContext* aStyleContext)
nsIFrame* aFrame)
{ {
nscoord lineHeight = -1; nsCOMPtr<nsIStyleContext> parentSC;
nsIStyleContext* sc; parentSC = getter_AddRefs(aStyleContext->GetParent());
aFrame->GetStyleContext(&sc); if (parentSC) {
const nsStyleFont* elementFont = nsnull; const nsStyleText* text = (const nsStyleText*)
if (nsnull != sc) { parentSC->GetStyleData(eStyleStruct_Text);
elementFont = (const nsStyleFont*)sc->GetStyleData(eStyleStruct_Font); if (eStyleUnit_Inherit == text->mLineHeight.GetUnit()) {
for (;;) { return GetNonInheritedLineHeightStyleContext(parentSC);
const nsStyleText* text = (const nsStyleText*) }
sc->GetStyleData(eStyleStruct_Text); }
if (nsnull != text) { return parentSC;
nsStyleUnit unit = text->mLineHeight.GetUnit(); }
if (eStyleUnit_Normal == unit) {
// Normal value static nscoord
#ifdef NOISY_VERTICAL_ALIGN ComputeLineHeight(nsIRenderingContext* aRenderingContext,
printf(" line-height: normal\n"); nsIStyleContext* aStyleContext)
#endif {
break; nscoord lineHeight = 0;
} else if (eStyleUnit_Factor == unit) {
// CSS2 spec says that the number is inherited, not the const nsStyleText* text = (const nsStyleText*)
// computed value. Therefore use the font size of the aStyleContext->GetStyleData(eStyleStruct_Text);
// element times the inherited number. const nsStyleFont* font = (const nsStyleFont*)
nscoord size = elementFont->mFont.size; aStyleContext->GetStyleData(eStyleStruct_Font);
lineHeight = nscoord(size * text->mLineHeight.GetFactorValue());
if (lineHeight < 0) { nsStyleUnit unit = text->mLineHeight.GetUnit();
lineHeight = -1; if (eStyleUnit_Inherit == unit) {
} // Inherit parents line-height value
#ifdef NOISY_VERTICAL_ALIGN nsCOMPtr<nsIStyleContext> parentSC =
printf(" line-height: factor=%g result=%d\n", getter_AddRefs(GetNonInheritedLineHeightStyleContext(aStyleContext));
text->mLineHeight.GetFactorValue(), lineHeight); if (parentSC) {
#endif text = (const nsStyleText*) parentSC->GetStyleData(eStyleStruct_Text);
break; unit = text->mLineHeight.GetUnit();
} if (eStyleUnit_Percent == unit) {
else if (eStyleUnit_Coord == unit) { // For percent, we inherit the computed value so updated the
lineHeight = text->mLineHeight.GetCoordValue(); // font to use the parent's font not our font.
if (lineHeight < 0) { font = (const nsStyleFont*) parentSC->GetStyleData(eStyleStruct_Font);
lineHeight = -1;
}
break;
}
else if (eStyleUnit_Percent == unit) {
// XXX This could arguably be the font-metrics actual height
// instead since the spec says use the computed height.
const nsStyleFont* font = (const nsStyleFont*)
sc->GetStyleData(eStyleStruct_Font);
nscoord size = font->mFont.size;
lineHeight = nscoord(size * text->mLineHeight.GetPercentValue());
if (lineHeight < 0) {
lineHeight = -1;
}
break;
}
else if (eStyleUnit_Inherit == unit) {
nsIStyleContext* parentSC;
parentSC = sc->GetParent();
if (nsnull == parentSC) {
// Note: Break before releasing to avoid double-releasing sc
break;
}
NS_RELEASE(sc);
sc = parentSC;
}
else {
// other units are not part of the spec so don't bother
// looping
break;
}
} }
} }
NS_RELEASE(sc);
} }
if (eStyleUnit_Coord == unit) {
// For length values just use the pre-computed value
lineHeight = text->mLineHeight.GetCoordValue();
}
else {
// For "normal", factor or percentage units the computed value of
// the line-height property is found by multiplying the factor by
// the font's <b>actual</b> height. For "normal" we use a factor
// value of "1.0".
float factor = 1.0f;
if (eStyleUnit_Factor == unit) {
factor = text->mLineHeight.GetFactorValue();
}
else if (eStyleUnit_Percent == unit) {
factor = text->mLineHeight.GetPercentValue();
}
aRenderingContext->SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext->GetFontMetrics(*getter_AddRefs(fm));
if (fm) {
fm->GetHeight(lineHeight);
}
#ifdef DEBUG_kipp
// Note: we normally use the actual font height for computing the
// line-height raw value from the style context. On systems where
// they disagree the actual font height is more appropriate. This
// little hack lets us override that behavior to allow for more
// precise layout in the face of imprecise fonts.
static PRBool useComputedHeight = PR_FALSE;
#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
static PRBool firstTime = 1;
if (firstTime) {
if (getenv("GECKO_USE_COMPUTED_HEIGHT")) {
useComputedHeight = PR_TRUE;
}
firstTime = 0;
}
#endif
if (useComputedHeight) {
lineHeight = font->mFont.size;
}
#endif
lineHeight = NSToCoordRound(factor * lineHeight);
}
return lineHeight;
}
nscoord
nsHTMLReflowState::CalcLineHeight(nsIPresContext& aPresContext,
nsIRenderingContext* aRenderingContext,
nsIFrame* aFrame)
{
nscoord lineHeight = 0;
nsCOMPtr<nsIStyleContext> sc;
aFrame->GetStyleContext(getter_AddRefs(sc));
if (sc) {
lineHeight = ComputeLineHeight(aRenderingContext, sc);
}
if (lineHeight < 0) {
lineHeight = 0;
}
return lineHeight; return lineHeight;
} }