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" ]