Bug 585069, support ratio scaling for xul images, r=dbaron

This commit is contained in:
Neil Deakin 2011-08-05 15:24:24 -04:00
Родитель 1fd6189ec9
Коммит c22ec0f7c0
7 изменённых файлов: 403 добавлений и 86 удалений

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

@ -2696,89 +2696,9 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
tentHeight = nsPresContext::CSSPixelsToAppUnits(150);
}
// Now apply min/max-width/height - CSS 2.1 sections 10.4 and 10.7:
if (minWidth > maxWidth)
maxWidth = minWidth;
if (minHeight > maxHeight)
maxHeight = minHeight;
nscoord heightAtMaxWidth, heightAtMinWidth,
widthAtMaxHeight, widthAtMinHeight;
if (tentWidth > 0) {
heightAtMaxWidth = MULDIV(maxWidth, tentHeight, tentWidth);
if (heightAtMaxWidth < minHeight)
heightAtMaxWidth = minHeight;
heightAtMinWidth = MULDIV(minWidth, tentHeight, tentWidth);
if (heightAtMinWidth > maxHeight)
heightAtMinWidth = maxHeight;
} else {
heightAtMaxWidth = tentHeight;
heightAtMinWidth = tentHeight;
}
if (tentHeight > 0) {
widthAtMaxHeight = MULDIV(maxHeight, tentWidth, tentHeight);
if (widthAtMaxHeight < minWidth)
widthAtMaxHeight = minWidth;
widthAtMinHeight = MULDIV(minHeight, tentWidth, tentHeight);
if (widthAtMinHeight > maxWidth)
widthAtMinHeight = maxWidth;
} else {
widthAtMaxHeight = tentWidth;
widthAtMinHeight = tentWidth;
}
// The table at http://www.w3.org/TR/CSS21/visudet.html#min-max-widths :
if (tentWidth > maxWidth) {
if (tentHeight > maxHeight) {
if (PRInt64(maxWidth) * PRInt64(tentHeight) <=
PRInt64(maxHeight) * PRInt64(tentWidth)) {
width = maxWidth;
height = heightAtMaxWidth;
} else {
width = widthAtMaxHeight;
height = maxHeight;
}
} else {
// This also covers "(w > max-width) and (h < min-height)" since in
// that case (max-width/w < 1), and with (h < min-height):
// max(max-width * h/w, min-height) == min-height
width = maxWidth;
height = heightAtMaxWidth;
}
} else if (tentWidth < minWidth) {
if (tentHeight < minHeight) {
if (PRInt64(minWidth) * PRInt64(tentHeight) <=
PRInt64(minHeight) * PRInt64(tentWidth)) {
width = widthAtMinHeight;
height = minHeight;
} else {
width = minWidth;
height = heightAtMinWidth;
}
} else {
// This also covers "(w < min-width) and (h > max-height)" since in
// that case (min-width/w > 1), and with (h > max-height):
// min(min-width * h/w, max-height) == max-height
width = minWidth;
height = heightAtMinWidth;
}
} else {
if (tentHeight > maxHeight) {
width = widthAtMaxHeight;
height = maxHeight;
} else if (tentHeight < minHeight) {
width = widthAtMinHeight;
height = minHeight;
} else {
width = tentWidth;
height = tentHeight;
}
}
return ComputeAutoSizeWithIntrinsicDimensions(minWidth, minHeight,
maxWidth, maxHeight,
tentWidth, tentHeight);
} else {
// 'auto' width, non-'auto' height
@ -2819,6 +2739,99 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
return nsSize(width, height);
}
nsSize
nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight,
nscoord maxWidth, nscoord maxHeight,
nscoord tentWidth, nscoord tentHeight)
{
// Now apply min/max-width/height - CSS 2.1 sections 10.4 and 10.7:
if (minWidth > maxWidth)
maxWidth = minWidth;
if (minHeight > maxHeight)
maxHeight = minHeight;
nscoord heightAtMaxWidth, heightAtMinWidth,
widthAtMaxHeight, widthAtMinHeight;
if (tentWidth > 0) {
heightAtMaxWidth = MULDIV(maxWidth, tentHeight, tentWidth);
if (heightAtMaxWidth < minHeight)
heightAtMaxWidth = minHeight;
heightAtMinWidth = MULDIV(minWidth, tentHeight, tentWidth);
if (heightAtMinWidth > maxHeight)
heightAtMinWidth = maxHeight;
} else {
heightAtMaxWidth = tentHeight;
heightAtMinWidth = tentHeight;
}
if (tentHeight > 0) {
widthAtMaxHeight = MULDIV(maxHeight, tentWidth, tentHeight);
if (widthAtMaxHeight < minWidth)
widthAtMaxHeight = minWidth;
widthAtMinHeight = MULDIV(minHeight, tentWidth, tentHeight);
if (widthAtMinHeight > maxWidth)
widthAtMinHeight = maxWidth;
} else {
widthAtMaxHeight = tentWidth;
widthAtMinHeight = tentWidth;
}
// The table at http://www.w3.org/TR/CSS21/visudet.html#min-max-widths :
nscoord width, height;
if (tentWidth > maxWidth) {
if (tentHeight > maxHeight) {
if (PRInt64(maxWidth) * PRInt64(tentHeight) <=
PRInt64(maxHeight) * PRInt64(tentWidth)) {
width = maxWidth;
height = heightAtMaxWidth;
} else {
width = widthAtMaxHeight;
height = maxHeight;
}
} else {
// This also covers "(w > max-width) and (h < min-height)" since in
// that case (max-width/w < 1), and with (h < min-height):
// max(max-width * h/w, min-height) == min-height
width = maxWidth;
height = heightAtMaxWidth;
}
} else if (tentWidth < minWidth) {
if (tentHeight < minHeight) {
if (PRInt64(minWidth) * PRInt64(tentHeight) <=
PRInt64(minHeight) * PRInt64(tentWidth)) {
width = widthAtMinHeight;
height = minHeight;
} else {
width = minWidth;
height = heightAtMinWidth;
}
} else {
// This also covers "(w < min-width) and (h > max-height)" since in
// that case (min-width/w > 1), and with (h > max-height):
// min(min-width * h/w, max-height) == max-height
width = minWidth;
height = heightAtMinWidth;
}
} else {
if (tentHeight > maxHeight) {
width = widthAtMaxHeight;
height = maxHeight;
} else if (tentHeight < minHeight) {
width = widthAtMinHeight;
height = minHeight;
} else {
width = tentWidth;
height = tentHeight;
}
}
return nsSize(width, height);
}
/* static */ nscoord
nsLayoutUtils::MinWidthFromInline(nsIFrame* aFrame,
nsRenderingContext* aRenderingContext)

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

@ -916,6 +916,16 @@ public:
nsSize aIntrinsicRatio, nsSize aCBSize,
nsSize aMargin, nsSize aBorder, nsSize aPadding);
/*
* Calculate the used values for 'width' and 'height' when width
* and height are 'auto'. The tentWidth and tentHeight arguments should be
* the result of applying the rules for computing intrinsic sizes and ratios.
* as specified by CSS 2.1 sections 10.3.2 and 10.6.2
*/
static nsSize ComputeAutoSizeWithIntrinsicDimensions(nscoord minWidth, nscoord minHeight,
nscoord maxWidth, nscoord maxHeight,
nscoord tentWidth, nscoord tentHeight);
// Implement nsIFrame::GetPrefWidth in terms of nsIFrame::AddInlinePrefWidth
static nscoord PrefWidthFromInline(nsIFrame* aFrame,
nsRenderingContext* aRenderingContext);

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

@ -0,0 +1,115 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:style>
div { margin: 0px; line-height: 0px; }
div div { background: blue; display: inline; float: left; }
</html:style>
<html:div><html:img
src="image4x3.png" style="width: 40px; height: 30px;"/><html:img
src="image4x3.png" style="width: 80px; height: 20px;"/><html:img
src="image4x3.png" style="width: 10px; height: 70px;"/><html:img
src="image4x3.png" style="width: 80px; height: 60px;"/><html:img
src="image4x3.png" style="width: 80px; height: 60px;"/><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/><html:img
src="image4x3.png" style="width: 40px; height: 30px; border: 8px solid green;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 80px; height: 64px; border: 8px solid yellow;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 72px; height: 58px; border: 8px solid green;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid yellow;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid green;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 74px; height: 53px; border: solid yellow; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 18px; height: 11px; border: solid green; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 40px; height: 30px;"/><html:img
src="image4x3.png" style="width: 80px; height: 20px;"/><html:img
src="image4x3.png" style="width: 10px; height: 70px;"/><html:img
src="image4x3.png" style="width: 80px; height: 60px;"/><html:img
src="image4x3.png" style="height: 80px; height: 60px;"/><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/><html:img
src="image4x3.png" style="width: 60px; height: 25px;"/><html:img
src="image4x3.png" style="width: 20px; height: 75px;"/><html:img
src="image4x3.png" style="width: 80px; height: 64px; padding: 8px; -moz-box-sizing: border-box;"/><html:img
src="image4x3.png" style="width: 72px; height: 58px; padding: 8px; -moz-box-sizing: border-box;"/><html:img
src="image4x3.png" style="width: 24px; height: 22px; padding: 8px; -moz-box-sizing: border-box;"/><html:img
src="image4x3.png" style="width: 24px; height: 22px; padding: 8px; -moz-box-sizing: border-box;"/><html:img
src="image4x3.png" style="width: 67px; height: 60px; padding: 4px 2px 8px 1px; -moz-box-sizing: border-box;"/><html:img
src="image4x3.png" style="width: 11px; height: 18px; padding: 4px 2px 8px 1px; -moz-box-sizing: border-box;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 30px; height: 22.5px"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 20px; height: 15px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width 30px; height: 22.5px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid green;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid green;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 40px; height: 30px;"/><html:img
src="image4x3.png" style="width: 40px; height: 30px;"/><html:img
src="image4x3.png" style="width: 40px; height: 30px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 60px; height: 49px; border: 8px solid green;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 112px; height: 88px; border: 8px solid yellow;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 96px; height: 76px; border: 8px solid green;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 112px; height: 88px; border: 8px solid yellow;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 106px; height: 77px; border: solid yellow; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/>
</html:div>
<html:div><html:img
src="image4x3.png" style="width: 60px; height: 45px;"/><html:img
src="image4x3.png" style="width: 120px; height: 90px;"/><html:img
src="image4x3.png" style="width 60px; height: 45px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 60px; height: 49px; padding: 8px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 112px; height: 88px; padding: 8px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 96px; height: 76px; padding: 8px;"/><html:img
src="image4x3.png" style="-moz-box-sizing: border-box; width: 112px; height: 88px; padding: 8px;"/>
</html:div>
<html:div><html:div
style="width: 20px; height: 15px;"/><html:div
style="width: 80px; height: 60px;"/><html:div
style="width: 40px; height: 30px;"/><html:div
style="width: 10px; height: 8px;"/><html:div
style="width: 10px; height: 8px;"/>
</html:div>
<html:div><html:div style="width: 20px; height: 15px;"/></html:div>
<html:div><html:div style="width: 20px; height: 15px;"/></html:div>
<html:div><html:div style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid green;"/></html:div>
<html:div><html:div style="-moz-box-sizing: border-box; width: 24px; height: 22px; border: 8px solid green;"/></html:div>
</window>

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

@ -0,0 +1,123 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox align="end">
<image src="image4x3.png"/>
<image src="image4x3.png" width="80" height="20"/>
<image src="image4x3.png" width="10" height="70"/>
<image src="image4x3.png" width="80"/>
<image src="image4x3.png" height="60"/>
<image src="image4x3.png" width="20"/>
<image src="image4x3.png" height="15"/>
<image src="image4x3.png" style="border: 8px solid green;"/>
<image src="image4x3.png" width="80" style="border: 8px solid yellow;"/>
<image src="image4x3.png" height="58" style="border: 8px solid green;"/>
<image src="image4x3.png" width="24" style="border: 8px solid yellow;"/>
<image src="image4x3.png" height="22" style="border: 8px solid green;"/>
<image src="image4x3.png" width="74"
style="border: 1px solid yellow; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/>
<image src="image4x3.png" height="11"
style="border: 1px solid green; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" style="width: auto; height: auto;"/>
<image src="image4x3.png" style="width: 80px; height: 20px;"/>
<image src="image4x3.png" style="width: 10px; height: 70px;"/>
<image src="image4x3.png" style="width: 80px;"/>
<image src="image4x3.png" style="height: 60px;"/>
<image src="image4x3.png" style="width: 20px;"/>
<image src="image4x3.png" style="height: 15px;"/>
<image src="image4x3.png" style="width: 80px; height: 20px;" width="60" height="25"/>
<image src="image4x3.png" style="width: 10px; height: 70px;" width="20" height="75"/>
<image src="image4x3.png" style="width: 80px; padding: 8px;"/>
<image src="image4x3.png" style="height: 58px; padding: 8px;"/>
<image src="image4x3.png" style="width: 24px; padding: 8px;"/>
<image src="image4x3.png" style="height: 22px; padding: 8px;"/>
<image src="image4x3.png" style="width: 67px; padding: 4px 2px 8px 1px"/>
<image src="image4x3.png" style="height: 18px; padding: 4px 2px 8px 1px"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" maxwidth="20"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" maxheight="15"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" maxwidth="30" maxheight="25"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" style="max-width: 20px;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" style="max-height: 15px;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" style="max-width: 30px; max-height: 25px;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" maxwidth="24" style="border: 8px solid green;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" maxheight="22" style="border: 8px solid green;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" minwidth="20"/>
<image src="image4x3.png" minheight="20"/>
<image src="image4x3.png" minwidth="20" minheight="25"/>
<image src="image4x3.png" minwidth="60" style="border: 8px solid green;"/>
<image src="image4x3.png" minheight="88" style="border: 8px solid yellow;"/>
<image src="image4x3.png" minwidth="90" minheight="76" style="border: 8px solid green;"/>
<image src="image4x3.png" minwidth="112" minheight="76" style="border: 8px solid yellow;"/>
<image src="image4x3.png" minwidth="106"
style="border: 1px solid yellow; border-top-width: 1px; border-right-width: 2px; border-bottom-width: 4px; border-left-width: 8px;"/>
</hbox>
<hbox align="end">
<image src="image4x3.png" style="min-width: 60px;"/>
<image src="image4x3.png" style="min-height: 90px;"/>
<image src="image4x3.png" style="min-width 41px; min-height: 45px;"/>
<image src="image4x3.png" style="min-width: 60px; padding: 8px;"/>
<image src="image4x3.png" style="min-height: 88px; padding: 8px;"/>
<image src="image4x3.png" style="min-width: 90px; min-height: 76px; padding: 8px;"/>
<image src="image4x3.png" style="min-width: 112px; min-height: 76px; padding: 8px;"/>
</hbox>
<hbox align="start">
<image style="width: auto; height: auto; list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px);"/>
<image width="80" style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px);"/>
<image height="30" style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px);"/>
<image style="width: 10px; list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 21px, 5px);"/>
<image style="height: 8px; list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 21px, 5px);"/>
</hbox>
<hbox align="end">
<image maxwidth="20"
style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px);"/>
</hbox>
<hbox align="end">
<image maxheight="15"
style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px);"/>
</hbox>
<hbox align="end">
<image maxwidth="24"
style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px); border: 8px solid green;"/>
</hbox>
<hbox align="end">
<image maxheight="22"
style="list-style-image: url(image4x3.png); -moz-image-region: rect(5px, 25px, 20px, 5px); border: 8px solid green;"/>
</hbox>
</window>

Двоичные данные
layout/xul/base/reftest/image4x3.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 176 B

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

@ -1,3 +1,4 @@
== textbox-multiline-noresize.xul textbox-multiline-ref.xul
!= textbox-multiline-resize.xul textbox-multiline-ref.xul
== popup-explicit-size.xul popup-explicit-size-ref.xul
== image-size.xul image-size-ref.xul

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

@ -440,7 +440,6 @@ nsImageBoxFrame::GetImageSize()
}
}
/**
* Ok return our dimensions
*/
@ -456,12 +455,68 @@ nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState)
size = nsSize(mSubRect.width, mSubRect.height);
else
size = mImageSize;
AddBorderAndPadding(size);
nsSize intrinsicSize = size;
nsMargin borderPadding(0,0,0,0);
GetBorderAndPadding(borderPadding);
size.width += borderPadding.LeftRight();
size.height += borderPadding.TopBottom();
PRBool widthSet, heightSet;
nsIBox::AddCSSPrefSize(this, size, widthSet, heightSet);
NS_ASSERTION(size.width != NS_INTRINSICSIZE && size.height != NS_INTRINSICSIZE,
"non-nintrinsic size expected");
nsSize minSize = GetMinSize(aState);
nsSize maxSize = GetMaxSize(aState);
nsSize maxSize = GetMaxSize(aState);
if (!widthSet && !heightSet) {
if (minSize.width != NS_INTRINSICSIZE)
minSize.width -= borderPadding.LeftRight();
if (minSize.height != NS_INTRINSICSIZE)
minSize.height -= borderPadding.TopBottom();
if (maxSize.width != NS_INTRINSICSIZE)
maxSize.width -= borderPadding.LeftRight();
if (maxSize.height != NS_INTRINSICSIZE)
maxSize.height -= borderPadding.TopBottom();
size = nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(minSize.width, minSize.height,
maxSize.width, maxSize.height,
intrinsicSize.width, intrinsicSize.height);
NS_ASSERTION(size.width != NS_INTRINSICSIZE && size.height != NS_INTRINSICSIZE,
"non-nintrinsic size expected");
size.width += borderPadding.LeftRight();
size.height += borderPadding.TopBottom();
return size;
}
if (!widthSet) {
if (intrinsicSize.height > 0) {
// Subtract off the border and padding from the height because the
// content-box needs to be used to determine the ratio
nscoord height = size.height - borderPadding.TopBottom();
size.width = nscoord(PRInt64(height) * PRInt64(intrinsicSize.width) /
PRInt64(intrinsicSize.height));
}
else {
size.width = intrinsicSize.width;
}
size.width += borderPadding.LeftRight();
}
else if (!heightSet) {
if (intrinsicSize.width > 0) {
nscoord width = size.width - borderPadding.LeftRight();
size.height = nscoord(PRInt64(width) * PRInt64(intrinsicSize.height) /
PRInt64(intrinsicSize.width));
}
else {
size.height = intrinsicSize.height;
}
size.height += borderPadding.TopBottom();
}
return BoundsCheck(minSize, size, maxSize);
}