Bug 585069, support ratio scaling for xul images, r=dbaron
authorNeil Deakin <neil@mozilla.com>
Fri, 05 Aug 2011 15:24:24 -0400
changeset 73921 7fece42cb99a9c3637b0926e43aac9156dfe1976
parent 73920 7eda7df522d1c276f41b580df7fd2d6bee756ecc
child 73922 3985e7570ab65a24576bb8ead0286d5c810b0167
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersdbaron
bugs585069
milestone8.0a1
Bug 585069, support ratio scaling for xul images, r=dbaron
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/xul/base/reftest/image-size-ref.xul
layout/xul/base/reftest/image-size.xul
layout/xul/base/reftest/image4x3.png
layout/xul/base/reftest/reftest.list
layout/xul/base/src/nsImageBoxFrame.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2691,99 +2691,19 @@ nsLayoutUtils::ComputeSizeWithIntrinsicD
       if (hasIntrinsicHeight) {
         tentHeight = intrinsicHeight;
       } else if (aIntrinsicRatio.width > 0) {
         tentHeight = MULDIV(tentWidth, aIntrinsicRatio.height, aIntrinsicRatio.width);
       } else {
         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
       height = NS_CSS_MINMAX(height, minHeight, maxHeight);
       if (aIntrinsicRatio.height > 0) {
         width = MULDIV(height, aIntrinsicRatio.width, aIntrinsicRatio.height);
       } else if (hasIntrinsicWidth) {
         width = intrinsicWidth;
@@ -2814,16 +2734,109 @@ nsLayoutUtils::ComputeSizeWithIntrinsicD
       height = NS_CSS_MINMAX(height, minHeight, maxHeight);
 
     }
   }
 
   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)
 {
   nsIFrame::InlineMinWidthData data;
   DISPLAY_MIN_WIDTH(aFrame, data.prevLines);
   aFrame->AddInlineMinWidth(aRenderingContext, &data);
   data.ForceBreak(aRenderingContext);
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -911,16 +911,26 @@ public:
    *   http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
    */
   static nsSize ComputeSizeWithIntrinsicDimensions(
                     nsRenderingContext* aRenderingContext, nsIFrame* aFrame,
                     const nsIFrame::IntrinsicSize& aIntrinsicSize,
                     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);
 
   // Implement nsIFrame::GetMinWidth in terms of nsIFrame::AddInlineMinWidth
   static nscoord MinWidthFromInline(nsIFrame* aFrame,
                                     nsRenderingContext* aRenderingContext);
 
new file mode 100644
--- /dev/null
+++ b/layout/xul/base/reftest/image-size-ref.xul
@@ -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>
new file mode 100644
--- /dev/null
+++ b/layout/xul/base/reftest/image-size.xul
@@ -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>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6719bf5cececea4cbaba4a2c7e71e6b18f6a90d5
GIT binary patch
literal 176
zc%17D@N?(olHy`uVBq!ia0vp^8bB<^!2~2P?myiHq{=;A978;K-%c~+YcSwp4nDHK
zaXPc&jFUZK?H1lwLN>jAJ*gwlRO`dfXZMc$?2q2BBfjzS`afN>&sZfL54?2HwAkM}
zC;8-kqrk;!Au7g;rzNB=ayz@iBh5|s;3=2hS%DMJ{95>L+nGCmHn4i#uv_#p$duPq
c?!xl;kRNP2_s5m506Kxe)78&qol`;+0E)dy&Hw-a
--- a/layout/xul/base/reftest/reftest.list
+++ b/layout/xul/base/reftest/reftest.list
@@ -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
--- a/layout/xul/base/src/nsImageBoxFrame.cpp
+++ b/layout/xul/base/src/nsImageBoxFrame.cpp
@@ -435,38 +435,93 @@ nsImageBoxFrame::GetImageSize()
     mImageSize.width = mIntrinsicSize.width;
     mImageSize.height = mIntrinsicSize.height;
   } else {
     mImageSize.width = 0;
     mImageSize.height = 0;
   }
 }
 
-
 /**
  * Ok return our dimensions
  */
 nsSize
 nsImageBoxFrame::GetPrefSize(nsBoxLayoutState& aState)
 {
   nsSize size(0,0);
   DISPLAY_PREF_SIZE(this, size);
   if (DoesNeedRecalc(mImageSize))
      GetImageSize();
 
   if (!mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0))
     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);
 }
 
 nsSize
 nsImageBoxFrame::GetMinSize(nsBoxLayoutState& aState)
 {
   // An image can always scale down to (0,0).