зеркало из https://github.com/mozilla/pjs.git
Implement correct intrinsic width calculation (for container) for elements with specified height properties and an intrinsic ratio. b=364066 r+sr=bzbarsky
This commit is contained in:
Родитель
1a71565259
Коммит
01e481e23d
|
@ -1253,6 +1253,67 @@ nsLayoutUtils::GetAbsoluteCoord(const nsStyleCoord& aStyle,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
GetPercentHeight(const nsStyleCoord& aStyle,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord& aResult)
|
||||
{
|
||||
if (eStyleUnit_Percent != aStyle.GetUnit())
|
||||
return PR_FALSE;
|
||||
|
||||
nsIFrame *f;
|
||||
for (f = aFrame->GetParent(); f && !f->IsContainingBlock();
|
||||
f = f->GetParent())
|
||||
;
|
||||
if (!f) {
|
||||
NS_NOTREACHED("top of frame tree not a containing block");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
const nsStylePosition *pos = f->GetStylePosition();
|
||||
nscoord h;
|
||||
if (!nsLayoutUtils::
|
||||
GetAbsoluteCoord(pos->mHeight, aRenderingContext, f, h) &&
|
||||
!GetPercentHeight(pos->mHeight, aRenderingContext, f, h)) {
|
||||
NS_ASSERTION(pos->mHeight.GetUnit() == eStyleUnit_Auto ||
|
||||
pos->mHeight.GetUnit() == eStyleUnit_Percent,
|
||||
"unknown height unit");
|
||||
// There's no basis for the percentage height, so it acts like auto.
|
||||
// Should we consider a max-height < min-height pair a basis for
|
||||
// percentage heights? The spec is somewhat unclear, and not doing
|
||||
// so is simpler and avoids troubling discontinuities in behavior,
|
||||
// so I'll choose not to. -LDB
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nscoord maxh;
|
||||
if (nsLayoutUtils::
|
||||
GetAbsoluteCoord(pos->mMaxHeight, aRenderingContext, f, maxh) ||
|
||||
GetPercentHeight(pos->mMaxHeight, aRenderingContext, f, maxh)) {
|
||||
if (maxh < h)
|
||||
h = maxh;
|
||||
} else {
|
||||
NS_ASSERTION(pos->mMaxHeight.GetUnit() == eStyleUnit_None ||
|
||||
pos->mMaxHeight.GetUnit() == eStyleUnit_Percent,
|
||||
"unknown max-height unit");
|
||||
}
|
||||
|
||||
nscoord minh;
|
||||
if (nsLayoutUtils::
|
||||
GetAbsoluteCoord(pos->mMinHeight, aRenderingContext, f, minh) ||
|
||||
GetPercentHeight(pos->mMinHeight, aRenderingContext, f, minh)) {
|
||||
if (minh > h)
|
||||
h = minh;
|
||||
} else {
|
||||
NS_ASSERTION(pos->mMaxHeight.GetUnit() == eStyleUnit_Percent,
|
||||
"unknown min-height unit");
|
||||
}
|
||||
|
||||
aResult = NSToCoordRound(aStyle.GetPercentValue() * h);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Handles only -moz-intrinsic and -moz-min-intrinsic, and
|
||||
// -moz-shrink-wrap for min-width and max-width, since the others
|
||||
// (-moz-shrink-wrap for width, and -moz-fill) have no effect on
|
||||
|
@ -1369,6 +1430,43 @@ nsLayoutUtils::IntrinsicForContainer(nsIRenderingContext *aRenderingContext,
|
|||
printf(" %s intrinsic width from frame is %d.\n",
|
||||
aType == MIN_WIDTH ? "min" : "pref", result);
|
||||
#endif
|
||||
|
||||
// Handle elements with an intrinsic ratio (or size) and a specified
|
||||
// height, min-height, or max-height.
|
||||
const nsStyleCoord &styleHeight = stylePos->mHeight;
|
||||
const nsStyleCoord &styleMinHeight = stylePos->mMinHeight;
|
||||
const nsStyleCoord &styleMaxHeight = stylePos->mMaxHeight;
|
||||
if (styleHeight.GetUnit() != eStyleUnit_Auto ||
|
||||
!(styleMinHeight.GetUnit() == eStyleUnit_Coord &&
|
||||
styleMinHeight.GetCoordValue() == 0) ||
|
||||
styleMaxHeight.GetUnit() != eStyleUnit_None) {
|
||||
|
||||
nsSize ratio = aFrame->GetIntrinsicRatio();
|
||||
|
||||
if (ratio.height != 0) {
|
||||
|
||||
nscoord h;
|
||||
if (GetAbsoluteCoord(styleHeight, aRenderingContext, aFrame, h) ||
|
||||
GetPercentHeight(styleHeight, aRenderingContext, aFrame, h)) {
|
||||
result =
|
||||
NSToCoordRound(h * (float(ratio.width) / float(ratio.height)));
|
||||
}
|
||||
|
||||
if (GetAbsoluteCoord(styleMaxHeight, aRenderingContext, aFrame, h) ||
|
||||
GetPercentHeight(styleMaxHeight, aRenderingContext, aFrame, h)) {
|
||||
h = NSToCoordRound(h * (float(ratio.width) / float(ratio.height)));
|
||||
if (h < result)
|
||||
result = h;
|
||||
}
|
||||
|
||||
if (GetAbsoluteCoord(styleMinHeight, aRenderingContext, aFrame, h) ||
|
||||
GetPercentHeight(styleMinHeight, aRenderingContext, aFrame, h)) {
|
||||
h = NSToCoordRound(h * (float(ratio.width) / float(ratio.height)));
|
||||
if (h > result)
|
||||
result = h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aFrame->GetType() == nsGkAtoms::tableFrame) {
|
||||
|
|
|
@ -3099,6 +3099,12 @@ nsFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsFrame::GetIntrinsicRatio()
|
||||
{
|
||||
return nsSize(0, 0);
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
|
||||
{
|
||||
|
|
|
@ -279,6 +279,7 @@ public:
|
|||
InlinePrefWidthData *aData);
|
||||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext);
|
||||
virtual nsSize GetIntrinsicRatio();
|
||||
|
||||
virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
|
|
@ -99,6 +99,12 @@ nsHTMLCanvasFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsHTMLCanvasFrame::GetIntrinsicRatio()
|
||||
{
|
||||
return GetCanvasSize();
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsHTMLCanvasFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nsSize GetIntrinsicRatio();
|
||||
|
||||
virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
|
|
@ -100,10 +100,10 @@ struct nsMargin;
|
|||
typedef class nsIFrame nsIBox;
|
||||
|
||||
// IID for the nsIFrame interface
|
||||
// 902aaa17-6433-4d96-86b3-fe1f4af41159
|
||||
// 4c0cfb5b-864d-46c5-ad78-b1b4de35a4c3
|
||||
#define NS_IFRAME_IID \
|
||||
{ 0x902aaa17, 0x6433, 0x4d96, \
|
||||
{ 0x86, 0xb3, 0xfe, 0x1f, 0x4a, 0xf4, 0x11, 0x59 } }
|
||||
{ 0x4c0cfb5b, 0x864d, 0x46c5, \
|
||||
{ 0xad, 0x78, 0xb1, 0xb4, 0xde, 0x35, 0xa4, 0xc3 } }
|
||||
|
||||
/**
|
||||
* Indication of how the frame can be split. This is used when doing runaround
|
||||
|
@ -1186,6 +1186,17 @@ public:
|
|||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext) = 0;
|
||||
|
||||
/*
|
||||
* Get the intrinsic ratio of this element, or nsSize(0,0) if it has
|
||||
* no intrinsic ratio. The intrinsic ratio is the ratio of the
|
||||
* height/width of a box with an intrinsic size or the intrinsic
|
||||
* aspect ratio of a scalable vector image without an intrinsic size.
|
||||
*
|
||||
* Either one of the sides may be zero, indicating a zero or infinite
|
||||
* ratio.
|
||||
*/
|
||||
virtual nsSize GetIntrinsicRatio() = 0;
|
||||
|
||||
/**
|
||||
* Compute the size that a frame will occupy. Called while
|
||||
* constructing the nsHTMLReflowState to be used to Reflow the frame,
|
||||
|
|
|
@ -769,6 +769,13 @@ nsImageFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsImageFrame::GetIntrinsicRatio()
|
||||
{
|
||||
EnsureIntrinsicSize(PresContext());
|
||||
return mIntrinsicSize;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
const nsDisplayListSet& aLists);
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nsSize GetIntrinsicRatio();
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Testcase, bug 364066</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<style type="text/css">
|
||||
|
||||
table { margin: 1px 0; border-spacing: 0; }
|
||||
td { padding: 0; border: 1px solid; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- solidblue.png is a 16x16 image -->
|
||||
|
||||
<table border><tr>
|
||||
|
||||
<td width="200">
|
||||
|
||||
<table><tr><td>
|
||||
<div style="height: 16px; width: 16px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 32px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 32px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 8px; width: 8px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 8px; width: 8px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 8px; width: 8px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 8px; width: 8px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
|
||||
</td><td width="200">
|
||||
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<div style="height: 40px; width: 32px"></div>
|
||||
</td></tr></table>
|
||||
|
||||
</td>
|
||||
|
||||
</tr></table>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Testcase, bug 364066</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<style type="text/css">
|
||||
|
||||
table { margin: 1px 0; border-spacing: 0; }
|
||||
td { padding: 0; border: 1px solid; line-height: 1px; }
|
||||
img { visibility: hidden; vertical-align: bottom; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- solidblue.png is a 16x16 image -->
|
||||
|
||||
<table border><tr>
|
||||
|
||||
<td width="200">
|
||||
|
||||
<table><tr><td><img src="solidblue.png"></td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="height: 32px">
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="min-height: 32px">
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="max-height: 8px">
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="height: 4px;min-height:8px">
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="max-height: 4px;min-height:8px">
|
||||
</td></tr></table>
|
||||
<table><tr><td>
|
||||
<img src="solidblue.png" style="height: 12px;max-height:8px">
|
||||
</td></tr></table>
|
||||
<table><tr><td><div style="height: 40px">
|
||||
<img src="solidblue.png" style="height: 80%">
|
||||
</div></td></tr></table>
|
||||
<table><tr><td><div style="height: 40px">
|
||||
<img src="solidblue.png" style="min-height: 80%">
|
||||
</div></td></tr></table>
|
||||
<table><tr><td><div style="height: 40px">
|
||||
<img src="solidblue.png" style="height: 60px; max-height: 80%">
|
||||
</div></td></tr></table>
|
||||
|
||||
</td><td width="200">
|
||||
|
||||
<table><tr><td><div style="height: 40px"><div style="height:100%"><div style="height:100%">
|
||||
<img src="solidblue.png" style="height: 80%">
|
||||
</div></div></div></td></tr></table>
|
||||
<table><tr><td><div style="height: 64px; max-height: 40px">
|
||||
<img src="solidblue.png" style="height: 80%">
|
||||
</div></td></tr></table>
|
||||
<table><tr><td><div style="height: 20px;min-height: 40px">
|
||||
<img src="solidblue.png" style="height: 80%">
|
||||
</div></td></tr></table>
|
||||
<table><tr><td><div style="height: 40px"><div style="height:20px; min-height:100%"><div style="height:100px;max-height:100%">
|
||||
<img src="solidblue.png" style="height: 80%">
|
||||
</div></div></div></td></tr></table>
|
||||
|
||||
</td>
|
||||
|
||||
</tr></table>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -174,6 +174,7 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 362901-1.html 362901-1-ref.html # mac b
|
|||
== 363637-1.html 363637-1-ref.html
|
||||
== 363874.html 363874-ref.html
|
||||
== 363874-max-width.html 363874-max-width-ref.html
|
||||
== 364066-1.html 364066-1-ref.html
|
||||
== 364079-1.html 364079-1-ref.html
|
||||
== 364861-1.html 364861-1-ref.html
|
||||
== 364862-1.html 364862-1-ref.html
|
||||
|
|
|
@ -67,6 +67,9 @@ private:
|
|||
|
||||
public:
|
||||
// nsIFrame:
|
||||
// XXX Should this implement intrinsic width methods (esp.
|
||||
// GetIntrinsicRatio)?
|
||||
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
|
Загрузка…
Ссылка в новой задаче