diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -303,18 +303,26 @@ nsHTMLReflowState::Init(nsPresContext* a
InitFrameType();
InitCBReflowState();
InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight, aBorder, aPadding);
InitResizeFlags(aPresContext);
- // Start loading the border image in layout instead of in paint
- aPresContext->LoadBorderImage(mStyleBorder->GetBorderImage(), this->frame);
+ // We have to start loading the border image now, because the
+ // border-image's width overrides only apply once the image is loaded.
+ // Starting the load of the image means we'll get a reflow when the
+ // image loads. (If we didn't do it now, and the image loaded between
+ // reflow and paint, we'd never get the notification, and our size
+ // would be wrong.)
+ imgIRequest *borderImage = mStyleBorder->GetBorderImage();
+ if (borderImage) {
+ aPresContext->LoadBorderImage(borderImage, frame);
+ }
NS_ASSERTION((mFrameType == NS_CSS_FRAME_TYPE_INLINE &&
!frame->IsFrameOfType(nsIFrame::eReplaced)) ||
frame->GetType() == nsGkAtoms::textFrame ||
mComputedWidth != NS_UNCONSTRAINEDSIZE,
"shouldn't use unconstrained widths anymore");
}
diff --git a/layout/reftests/border-image/border.png b/layout/reftests/border-image/border.png
deleted file mode 100644
Binary file layout/reftests/border-image/border.png has changed
diff --git a/layout/reftests/border-image/repeat-image-2.html b/layout/reftests/border-image/repeat-image-2.html
deleted file mode 100644
--- a/layout/reftests/border-image/repeat-image-2.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- test of -moz-border-image
-
-
-
-
-
-
-
-
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -474,17 +474,19 @@ nsChangeHint nsStyleBorder::CalcDifferen
#ifdef DEBUG
/* static */
nsChangeHint nsStyleBorder::MaxDifference()
{
return NS_STYLE_HINT_REFLOW;
}
#endif
-PRBool nsStyleBorder::ImageBorderDiffers() const {
+PRBool
+nsStyleBorder::ImageBorderDiffers() const
+{
return mActualBorder != (mHaveBorderImageWidth ? mBorderImageWidth : mBorder);
}
nsStyleOutline::nsStyleOutline(nsPresContext* aPresContext)
{
// spacing values not inherited
nsStyleCoord zero(0);
NS_FOR_CSS_SIDES(side) {
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -435,40 +435,42 @@ struct nsStyleBorder {
if (mBorderColors[aSide]) {
delete mBorderColors[aSide];
mBorderColors[aSide] = nsnull;
}
}
// Return whether aStyle is a visible style. Invisible styles cause
// the relevant computed border width to be 0.
+ // Note that this does *not* consider the effects of 'border-image':
+ // if border-style is none, but there is a loaded border image,
+ // HasVisibleStyle will be false even though there *is* a border.
// Defined in nsStyleStructInlines.h.
inline PRBool HasVisibleStyle(PRUint8 aSide);
// aBorderWidth is in twips
// Defined in nsStyleStructInlines.h.
inline void SetBorderWidth(PRUint8 aSide, nscoord aBorderWidth);
inline void SetBorderImageWidthOverride(PRUint8 aSide, nscoord aBorderWidth);
-
- // Regarding GetRoundedBorder() and GetActualBorder():
- // The process is computed ==[rounding]==> rounded == [including border-image]==> actual
-
// Get the actual border, in twips.
const nsMargin& GetActualBorder() const
{
if (IsBorderImageLoaded())
if (mHaveBorderImageWidth)
return mBorderImageWidth;
else
return mBorder;
else
return mActualBorder;
}
+ // Get the computed border (plus rounding). This does consider the
+ // effects of 'border-style: none', but does not consider
+ // 'border-image'.
const nsMargin& GetRoundedBorder() const
{
return mActualBorder;
}
// Get the actual border width for a particular side, in twips. Note that
// this is zero if and only if there is no border to be painted for this
// side. That is, this value takes into account the border style and the
@@ -550,27 +552,32 @@ struct nsStyleBorder {
mBorderStyle[aSide] &= ~BORDER_COLOR_SPECIAL;
mBorderStyle[aSide] |= BORDER_COLOR_FOREGROUND;
}
protected:
// mActualBorder holds the CSS2.1 actual border-width values. In
// particular, these widths take into account the border-style for the
// relevant side and the values are rounded to the nearest device pixel.
+ // However, they do *not* take into account the presence of
+ // border-image. See GetActualBorder above for how to really get the
+ // actual border.
nsMargin mActualBorder;
// mBorder holds the nscoord values for the border widths as they would be if
// all the border-style values were visible (not hidden or none). This
- // member exists solely so that when we create structs using the copy
+ // member exists so that when we create structs using the copy
// constructor during style resolution the new structs will know what the
// specified values of the border were in case they have more specific rules
// setting the border style. Note that this isn't quite the CSS specified
// value, since this has had the enumerated border widths converted to
// lengths, and all lengths converted to twips. But it's not quite the
// computed value either. The values are rounded to the nearest device pixel
+ // We also use these values when we have a loaded border-image that
+ // does not have width overrides.
nsMargin mBorder;
PRUint8 mBorderStyle[4]; // [reset] See nsStyleConsts.h
nscolor mBorderColor[4]; // [reset] the colors to use for a simple border. not used
// if -moz-border-colors is specified
nsCOMPtr mBorderImage; // [reset]
diff --git a/layout/style/nsStyleStructInlines.h b/layout/style/nsStyleStructInlines.h
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -15,17 +15,17 @@
* The Original Code is nsStyleStructInlines.h.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* L. David Baron , Mozilla Corporation (original author)
- * Rob Arnold
+ * Rob Arnold
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -64,25 +64,28 @@ inline PRBool nsStyleBorder::HasVisibleS
{
PRUint8 style = GetBorderStyle(aSide);
return (style != NS_STYLE_BORDER_STYLE_NONE &&
style != NS_STYLE_BORDER_STYLE_HIDDEN);
}
inline void nsStyleBorder::SetBorderWidth(PRUint8 aSide, nscoord aBorderWidth)
{
- nscoord roundedWidth = NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
+ nscoord roundedWidth =
+ NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
mBorder.side(aSide) = roundedWidth;
if (HasVisibleStyle(aSide))
mActualBorder.side(aSide) = roundedWidth;
}
-inline void nsStyleBorder::SetBorderImageWidthOverride(PRUint8 aSide, nscoord aBorderWidth)
+inline void nsStyleBorder::SetBorderImageWidthOverride(PRUint8 aSide,
+ nscoord aBorderWidth)
{
- mBorderImageWidth.side(aSide) = NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
+ mBorderImageWidth.side(aSide) =
+ NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel);
}
inline void nsStyleBorder::RebuildActualBorderSide(PRUint8 aSide)
{
mActualBorder.side(aSide) = HasVisibleStyle(aSide) ? mBorder.side(aSide) : 0;
}
inline void nsStyleBorder::SetBorderStyle(PRUint8 aSide, PRUint8 aStyle)
@@ -95,18 +98,17 @@ inline void nsStyleBorder::SetBorderStyl
inline void nsStyleBorder::RebuildActualBorder()
{
NS_FOR_CSS_SIDES(side) {
RebuildActualBorderSide(side);
}
}
-inline PRBool nsStyleBorder::IsBorderImageLoaded() const {
- PRUint32 status = imgIRequest::STATUS_ERROR;
- if(!mBorderImage)
- return PR_FALSE;
-
- mBorderImage->GetImageStatus(&status);
- return (status & imgIRequest::STATUS_FRAME_COMPLETE) ? PR_TRUE : PR_FALSE;
+inline PRBool nsStyleBorder::IsBorderImageLoaded() const
+{
+ PRUint32 status;
+ return mBorderImage &&
+ NS_SUCCEEDED(mBorderImage->GetImageStatus(&status)) &&
+ (status & imgIRequest::STATUS_FRAME_COMPLETE);
}
#endif /* !defined(nsStyleStructInlines_h_) */
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -150,26 +150,26 @@ var gCSSProperties = {
invalid_values: [ "5%" ]
},
"-moz-border-image": {
domProp: "MozBorderImage",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "url('border.png') 27 27 27 27",
- "url('border.png') 27",
- "url('border.png') 27 27 27 27 repeat",
- "url('border.png') 27 27 27 27 / 1em",
- "url('border.png') 27 27 27 27 / 1em 1em 1em 1em repeat",
- "url('border.png') 27 27 27 27 / 1em 1em 1em 1em stretch round" ],
+ "url('border.png') 27",
+ "url('border.png') 27 27 27 27 repeat",
+ "url('border.png') 27 27 27 27 / 1em",
+ "url('border.png') 27 27 27 27 / 1em 1em 1em 1em repeat",
+ "url('border.png') 27 27 27 27 / 1em 1em 1em 1em stretch round" ],
invalid_values: [ "url('border.png')",
- "url('border.png') 27 27 27 27 27",
- "url('border.png') 27 27 27 27 / 1em 1em 1em 1em 1em",
- "url('border.png') / repeat",
- "url('border.png') 27 27 27 27 /" ]
+ "url('border.png') 27 27 27 27 27",
+ "url('border.png') 27 27 27 27 / 1em 1em 1em 1em 1em",
+ "url('border.png') / repeat",
+ "url('border.png') 27 27 27 27 /" ]
},
"-moz-border-left-colors": {
domProp: "MozBorderLeftColors",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "red green", "red #fc3", "#ff00cc", "currentColor", "blue currentColor orange currentColor" ],
invalid_values: [ "red none", "red inherit", "red, green" ]