diff --git a/content/base/src/nsRuleNode.cpp b/content/base/src/nsRuleNode.cpp index bc6dc92f0df..e5b57765667 100644 --- a/content/base/src/nsRuleNode.cpp +++ b/content/base/src/nsRuleNode.cpp @@ -888,8 +888,10 @@ static const PropertyCheckData ColorCheckProperties[] = { static const PropertyCheckData BackgroundCheckProperties[] = { CHECKDATA_PROP(nsCSSColor, mBackAttachment, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackRepeat, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsCSSColor, mBackClip, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackColor, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackImage, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsCSSColor, mBackOrigin, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackPositionX, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackPositionY, CHECKDATA_VALUE, PR_FALSE) }; @@ -3192,6 +3194,28 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, const nsCSSStruct bg->mBackgroundAttachment = parentBG->mBackgroundAttachment; } + // background-clip: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = colorData.mBackClip.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = parentBG->mBackgroundClip; + } + else if (eCSSUnit_Initial == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; + } + + // background-origin: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = colorData.mBackOrigin.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = parentBG->mBackgroundOrigin; + } + else if (eCSSUnit_Initial == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = NS_STYLE_BG_ORIGIN_PADDING; + } + // background-position: enum, length, percent (flags), inherit if (eCSSUnit_Percent == colorData.mBackPositionX.GetUnit()) { bg->mBackgroundXPosition = (nscoord)(100.0f * colorData.mBackPositionX.GetPercentValue()); diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 6acf29a024e..1ba53b922e4 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -89,6 +89,8 @@ #include "nsIDOMNSDocument.h" #include "nsIWidget.h" #include "nsContentUtils.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, @@ -396,6 +398,26 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, { NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE); + if (aSubType & NS_EVENT_BITS_CONTEXTMENU) { + nsCOMPtr prefService = + do_GetService(NS_PREFSERVICE_CONTRACTID); + + NS_ENSURE_TRUE(prefService, NS_ERROR_FAILURE); + + nsCOMPtr prefBranch; + prefService->GetBranch(nsnull, getter_AddRefs(prefBranch)); + + PRBool blockOnContextMenu = PR_FALSE; + // dom.disable.event.oncontextmenu ??? + prefBranch->GetBoolPref("pref.name.here", &blockOnContextMenu); + + // Only chrome is allowed to add a context menu listener if our + // pref is set to true. + if (blockOnContextMenu && !nsContentUtils::IsCallerChrome()) { + return NS_OK; + } + } + nsVoidArray* listeners = GetListenersByType(aType, aKey, PR_TRUE); //We asked the GetListenersByType to create the array if it had to. If it didn't diff --git a/content/html/style/src/nsCSSDeclaration.cpp b/content/html/style/src/nsCSSDeclaration.cpp index 02269ec745a..5c9b8f77ea6 100644 --- a/content/html/style/src/nsCSSDeclaration.cpp +++ b/content/html/style/src/nsCSSDeclaration.cpp @@ -166,7 +166,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackRepeat(aCopy.mBackRepeat), mBackAttachment(aCopy.mBackAttachment), mBackPositionX(aCopy.mBackPositionX), - mBackPositionY(aCopy.mBackPositionY) + mBackPositionY(aCopy.mBackPositionY), + mBackClip(aCopy.mBackClip), + mBackOrigin(aCopy.mBackOrigin) { MOZ_COUNT_CTOR(nsCSSColor); } @@ -195,6 +197,8 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackAttachment.AppendToString(buffer, eCSSProperty_background_attachment); mBackPositionX.AppendToString(buffer, eCSSProperty_background_x_position); mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); + mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); + mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1471,7 +1475,9 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1481,6 +1487,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_attachment: theColor->mBackAttachment = aValue; break; case eCSSProperty_background_x_position: theColor->mBackPositionX = aValue; break; case eCSSProperty_background_y_position: theColor->mBackPositionY = aValue; break; + case eCSSProperty__moz_background_clip: theColor->mBackClip = aValue; break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2310,7 +2318,9 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2322,6 +2332,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) CSS_CASE_IMPORTANT(eCSSProperty_background_attachment, Color, mBackAttachment); CSS_CASE_IMPORTANT(eCSSProperty_background_x_position, Color, mBackPositionX); CSS_CASE_IMPORTANT(eCSSProperty_background_y_position, Color, mBackPositionY); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_clip, Color, mBackClip); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_origin, Color, mBackOrigin); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3272,7 +3284,9 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3282,6 +3296,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_attachment: theColor->mBackAttachment.Reset(); break; case eCSSProperty_background_x_position: theColor->mBackPositionX.Reset(); break; case eCSSProperty_background_y_position: theColor->mBackPositionY.Reset(); break; + case eCSSProperty__moz_background_clip: theColor->mBackClip.Reset(); break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4100,7 +4116,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4111,6 +4129,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_attachment: aValue = theColor->mBackAttachment; break; case eCSSProperty_background_x_position: aValue = theColor->mBackPositionX; break; case eCSSProperty_background_y_position: aValue = theColor->mBackPositionY; break; + case eCSSProperty__moz_background_clip: aValue = theColor->mBackClip; break; + case eCSSProperty__moz_background_origin: aValue = theColor->mBackOrigin; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/content/html/style/src/nsCSSDeclaration.h b/content/html/style/src/nsCSSDeclaration.h index 7f336020995..94f109babf4 100644 --- a/content/html/style/src/nsCSSDeclaration.h +++ b/content/html/style/src/nsCSSDeclaration.h @@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackAttachment; nsCSSValue mBackPositionX; nsCSSValue mBackPositionY; + nsCSSValue mBackClip; + nsCSSValue mBackOrigin; }; struct nsCSSShadow { diff --git a/content/html/style/src/nsCSSParser.cpp b/content/html/style/src/nsCSSParser.cpp index 79c97fb3860..570057dc024 100644 --- a/content/html/style/src/nsCSSParser.cpp +++ b/content/html/style/src/nsCSSParser.cpp @@ -3748,11 +3748,17 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode, case eCSSProperty_background_attachment: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundAttachmentKTable); + case eCSSProperty__moz_background_clip: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundClipKTable); case eCSSProperty_background_color: return ParseVariant(aErrorCode, aValue, VARIANT_HCK, nsCSSProps::kBackgroundColorKTable); case eCSSProperty_background_image: return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull); + case eCSSProperty__moz_background_origin: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundOriginKTable); case eCSSProperty_background_repeat: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundRepeatKTable); @@ -4244,9 +4250,23 @@ PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsCSSDeclaration* aDe } PRInt32 index; - for (index = 0; index < numProps; index++) { + for (index = 0; index < numProps; ++index) { AppendValue(aDeclaration, kBackgroundIDs[index], values[index], aChangeHint); } + + // Background properties not settable from the shorthand get reset to their initial value + const PRInt32 numResetProps = 2; + static const nsCSSProperty kBackgroundResetIDs[numResetProps] = { + eCSSProperty__moz_background_clip, + eCSSProperty__moz_background_origin + }; + + nsCSSValue initial; + initial.SetInitialValue(); + for (index = 0; index < numResetProps; ++index) { + AppendValue(aDeclaration, kBackgroundResetIDs[index], initial, aChangeHint); + } + return PR_TRUE; } diff --git a/content/html/style/src/nsCSSStruct.cpp b/content/html/style/src/nsCSSStruct.cpp index 02269ec745a..5c9b8f77ea6 100644 --- a/content/html/style/src/nsCSSStruct.cpp +++ b/content/html/style/src/nsCSSStruct.cpp @@ -166,7 +166,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackRepeat(aCopy.mBackRepeat), mBackAttachment(aCopy.mBackAttachment), mBackPositionX(aCopy.mBackPositionX), - mBackPositionY(aCopy.mBackPositionY) + mBackPositionY(aCopy.mBackPositionY), + mBackClip(aCopy.mBackClip), + mBackOrigin(aCopy.mBackOrigin) { MOZ_COUNT_CTOR(nsCSSColor); } @@ -195,6 +197,8 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackAttachment.AppendToString(buffer, eCSSProperty_background_attachment); mBackPositionX.AppendToString(buffer, eCSSProperty_background_x_position); mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); + mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); + mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1471,7 +1475,9 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1481,6 +1487,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_attachment: theColor->mBackAttachment = aValue; break; case eCSSProperty_background_x_position: theColor->mBackPositionX = aValue; break; case eCSSProperty_background_y_position: theColor->mBackPositionY = aValue; break; + case eCSSProperty__moz_background_clip: theColor->mBackClip = aValue; break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2310,7 +2318,9 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2322,6 +2332,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) CSS_CASE_IMPORTANT(eCSSProperty_background_attachment, Color, mBackAttachment); CSS_CASE_IMPORTANT(eCSSProperty_background_x_position, Color, mBackPositionX); CSS_CASE_IMPORTANT(eCSSProperty_background_y_position, Color, mBackPositionY); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_clip, Color, mBackClip); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_origin, Color, mBackOrigin); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3272,7 +3284,9 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3282,6 +3296,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_attachment: theColor->mBackAttachment.Reset(); break; case eCSSProperty_background_x_position: theColor->mBackPositionX.Reset(); break; case eCSSProperty_background_y_position: theColor->mBackPositionY.Reset(); break; + case eCSSProperty__moz_background_clip: theColor->mBackClip.Reset(); break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4100,7 +4116,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4111,6 +4129,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_attachment: aValue = theColor->mBackAttachment; break; case eCSSProperty_background_x_position: aValue = theColor->mBackPositionX; break; case eCSSProperty_background_y_position: aValue = theColor->mBackPositionY; break; + case eCSSProperty__moz_background_clip: aValue = theColor->mBackClip; break; + case eCSSProperty__moz_background_origin: aValue = theColor->mBackOrigin; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/content/html/style/src/nsCSSStruct.h b/content/html/style/src/nsCSSStruct.h index 7f336020995..94f109babf4 100644 --- a/content/html/style/src/nsCSSStruct.h +++ b/content/html/style/src/nsCSSStruct.h @@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackAttachment; nsCSSValue mBackPositionX; nsCSSValue mBackPositionY; + nsCSSValue mBackClip; + nsCSSValue mBackOrigin; }; struct nsCSSShadow { diff --git a/content/html/style/src/nsCSSStyleRule.cpp b/content/html/style/src/nsCSSStyleRule.cpp index 0068e0962f8..d41b9570a60 100644 --- a/content/html/style/src/nsCSSStyleRule.cpp +++ b/content/html/style/src/nsCSSStyleRule.cpp @@ -2139,6 +2139,14 @@ MapColorForDeclaration(nsCSSDeclaration* aDecl, const nsStyleStructID& aID, nsCS aColor.mBackPositionX = ourColor->mBackPositionX; if (aColor.mBackPositionY.GetUnit() == eCSSUnit_Null && ourColor->mBackPositionY.GetUnit() != eCSSUnit_Null) aColor.mBackPositionY = ourColor->mBackPositionY; + + // background-clip: enum, inherit + if (aColor.mBackClip.GetUnit() == eCSSUnit_Null && ourColor->mBackClip.GetUnit() != eCSSUnit_Null) + aColor.mBackClip = ourColor->mBackClip; + + // background-origin: enum, inherit + if (aColor.mBackOrigin.GetUnit() == eCSSUnit_Null && ourColor->mBackOrigin.GetUnit() != eCSSUnit_Null) + aColor.mBackOrigin = ourColor->mBackOrigin; } return NS_OK; diff --git a/content/html/style/src/nsComputedDOMStyle.cpp b/content/html/style/src/nsComputedDOMStyle.cpp index d6ec7a3af5f..fbd9849a9d0 100644 --- a/content/html/style/src/nsComputedDOMStyle.cpp +++ b/content/html/style/src/nsComputedDOMStyle.cpp @@ -682,6 +682,30 @@ nsComputedDOMStyle::GetBackgroundAttachment(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundClip(nsIFrame *aFrame, + nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleBackground *background = nsnull; + GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame); + + PRUint8 clip = NS_STYLE_BG_CLIP_BORDER; + if (background) { + clip = background->mBackgroundClip; + } + + const nsAFlatCString& backgroundClip = + nsCSSProps::SearchKeywordTable(clip, + nsCSSProps::kBackgroundClipKTable); + + val->SetIdent(backgroundClip); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundColor(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -739,6 +763,30 @@ nsComputedDOMStyle::GetBackgroundImage(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundOrigin(nsIFrame *aFrame, + nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleBackground *background = nsnull; + GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame); + + PRUint8 origin = NS_STYLE_BG_ORIGIN_PADDING; + if (background) { + origin = background->mBackgroundOrigin; + } + + const nsAFlatCString& backgroundOrigin = + nsCSSProps::SearchKeywordTable(origin, + nsCSSProps::kBackgroundOriginKTable); + + val->SetIdent(backgroundOrigin); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -3571,6 +3619,8 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) \* ******************************* */ COMPUTED_STYLE_MAP_ENTRY(appearance, Appearance), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_clip, BackgroundClip), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_origin, BackgroundOrigin), COMPUTED_STYLE_MAP_ENTRY(binding, Binding), COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors, BorderBottomColors), COMPUTED_STYLE_MAP_ENTRY(border_left_colors, BorderLeftColors), diff --git a/content/html/style/src/nsComputedDOMStyle.h b/content/html/style/src/nsComputedDOMStyle.h index a4757ecde20..1a4ac4b44de 100644 --- a/content/html/style/src/nsComputedDOMStyle.h +++ b/content/html/style/src/nsComputedDOMStyle.h @@ -174,6 +174,8 @@ private: nsresult GetBackgroundColor(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundImage(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundClip(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue); /* Padding properties */ nsresult GetPadding(nsIFrame *aFrame, nsIDOMCSSValue** aValue); diff --git a/content/shared/public/nsCSSKeywordList.h b/content/shared/public/nsCSSKeywordList.h index 3207e2cc6bf..3f762a2d583 100644 --- a/content/shared/public/nsCSSKeywordList.h +++ b/content/shared/public/nsCSSKeywordList.h @@ -181,6 +181,7 @@ CSS_KEY(block, block) CSS_KEY(block-axis, block_axis) CSS_KEY(bold, bold) CSS_KEY(bolder, bolder) +CSS_KEY(border, border) CSS_KEY(border-box, border_box) CSS_KEY(both, both) CSS_KEY(bottom, bottom) @@ -203,6 +204,7 @@ CSS_KEY(cm, cm) CSS_KEY(code, code) CSS_KEY(collapse, collapse) CSS_KEY(condensed, condensed) +CSS_KEY(content, content) CSS_KEY(content-box, content_box) CSS_KEY(continuous, continuous) CSS_KEY(crop, crop) @@ -316,6 +318,7 @@ CSS_KEY(open-quote, open_quote) CSS_KEY(outset, outset) CSS_KEY(outside, outside) CSS_KEY(overline, overline) +CSS_KEY(padding, padding) CSS_KEY(padding-box, padding_box) CSS_KEY(pc, pc) CSS_KEY(pointer, pointer) diff --git a/content/shared/public/nsCSSPropList.h b/content/shared/public/nsCSSPropList.h index 32fbaea06d9..7c13710474a 100644 --- a/content/shared/public/nsCSSPropList.h +++ b/content/shared/public/nsCSSPropList.h @@ -109,8 +109,10 @@ CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, MozOu CSS_PROP(azimuth, azimuth, Azimuth, NS_STYLE_HINT_AURAL) CSS_PROP(background, background, Background, NS_STYLE_HINT_VISUAL) CSS_PROP(background-attachment, background_attachment, BackgroundAttachment, NS_STYLE_HINT_FRAMECHANGE) +CSS_PROP(-moz-background-clip, _moz_background_clip, MozBackgroundClip, NS_STYLE_HINT_VISUAL) CSS_PROP(background-color, background_color, BackgroundColor, NS_STYLE_HINT_VISUAL) CSS_PROP(background-image, background_image, BackgroundImage, NS_STYLE_HINT_VISUAL) +CSS_PROP(-moz-background-origin, _moz_background_origin, MozBackgroundOrigin, NS_STYLE_HINT_VISUAL) CSS_PROP(background-position, background_position, BackgroundPosition, NS_STYLE_HINT_VISUAL) CSS_PROP(background-repeat, background_repeat, BackgroundRepeat, NS_STYLE_HINT_VISUAL) CSS_PROP_INTERNAL(-x-background-x-position, background_x_position, BackgroundXPosition, NS_STYLE_HINT_VISUAL) // XXX bug 3935 diff --git a/content/shared/public/nsCSSProps.h b/content/shared/public/nsCSSProps.h index 8b203e993fd..bd77f3ae95b 100644 --- a/content/shared/public/nsCSSProps.h +++ b/content/shared/public/nsCSSProps.h @@ -87,7 +87,9 @@ public: static const PRInt32 kAppearanceKTable[]; static const PRInt32 kAzimuthKTable[]; static const PRInt32 kBackgroundAttachmentKTable[]; + static const PRInt32 kBackgroundClipKTable[]; static const PRInt32 kBackgroundColorKTable[]; + static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; static const PRInt32 kBorderCollapseKTable[]; static const PRInt32 kBorderColorKTable[]; diff --git a/content/shared/public/nsStyleStruct.h b/content/shared/public/nsStyleStruct.h index 9a5325d4617..34abbf57f14 100644 --- a/content/shared/public/nsStyleStruct.h +++ b/content/shared/public/nsStyleStruct.h @@ -156,10 +156,16 @@ struct nsStyleBackground : public nsStyleStruct { }; nsChangeHint CalcDifference(const nsStyleBackground& aOther) const; - - PRUint8 mBackgroundAttachment; // [reset] See nsStyleConsts.h - PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h - PRUint8 mBackgroundRepeat; // [reset] See nsStyleConsts.h + + // On Linux (others?), there is an extra byte being used up by + // inheritance so we only have 3 bytes to fit these 5 things into. + // Fortunately, the properties are enums which have few possible + // values. + PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundAttachment : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundClip : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundOrigin : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundRepeat : 4; // [reset] See nsStyleConsts.h nscolor mBackgroundColor; // [reset] nscoord mBackgroundXPosition; // [reset] diff --git a/content/shared/src/nsCSSProps.cpp b/content/shared/src/nsCSSProps.cpp index 15fc2a4f6fe..bb4f6d2821c 100644 --- a/content/shared/src/nsCSSProps.cpp +++ b/content/shared/src/nsCSSProps.cpp @@ -222,6 +222,19 @@ const PRInt32 nsCSSProps::kBackgroundColorKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundClipKTable[] = { + eCSSKeyword_border, NS_STYLE_BG_CLIP_BORDER, + eCSSKeyword_padding, NS_STYLE_BG_CLIP_PADDING, + -1,-1 +}; + +const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = { + eCSSKeyword_border, NS_STYLE_BG_ORIGIN_BORDER, + eCSSKeyword_padding, NS_STYLE_BG_ORIGIN_PADDING, + eCSSKeyword_content, NS_STYLE_BG_ORIGIN_CONTENT, + -1,-1 +}; + const PRInt32 nsCSSProps::kBackgroundRepeatKTable[] = { eCSSKeyword_no_repeat, NS_STYLE_BG_REPEAT_OFF, eCSSKeyword_repeat, NS_STYLE_BG_REPEAT_XY, @@ -920,6 +933,12 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_background_repeat: return SearchKeywordTable(aValue, kBackgroundRepeatKTable); + case eCSSProperty__moz_background_clip: + return SearchKeywordTable(aValue, kBackgroundClipKTable); + + case eCSSProperty__moz_background_origin: + return SearchKeywordTable(aValue, kBackgroundOriginKTable); + case eCSSProperty_background_x_position: return SearchKeywordTable(aValue, kBackgroundXPositionKTable); diff --git a/content/shared/src/nsStyleStruct.cpp b/content/shared/src/nsStyleStruct.cpp index 9f04af9204e..28747838e73 100644 --- a/content/shared/src/nsStyleStruct.cpp +++ b/content/shared/src/nsStyleStruct.cpp @@ -977,6 +977,8 @@ nsStyleBackground::nsStyleBackground(nsIPresContext* aPresContext) mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; + mBackgroundOrigin = NS_STYLE_BG_ORIGIN_PADDING; mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; mBackgroundXPosition = mBackgroundYPosition = 0; } @@ -986,7 +988,8 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) mBackgroundAttachment = aSource.mBackgroundAttachment; mBackgroundFlags = aSource.mBackgroundFlags; mBackgroundRepeat = aSource.mBackgroundRepeat; - + mBackgroundClip = aSource.mBackgroundClip; + mBackgroundOrigin = aSource.mBackgroundOrigin; mBackgroundColor = aSource.mBackgroundColor; mBackgroundXPosition = aSource.mBackgroundXPosition; mBackgroundYPosition = aSource.mBackgroundYPosition; @@ -1007,6 +1010,8 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) (mBackgroundColor == aOther.mBackgroundColor) && (mBackgroundXPosition == aOther.mBackgroundXPosition) && (mBackgroundYPosition == aOther.mBackgroundYPosition) && + (mBackgroundClip == aOther.mBackgroundClip) && + (mBackgroundOrigin == aOther.mBackgroundOrigin) && (mBackgroundImage == aOther.mBackgroundImage)) return NS_STYLE_HINT_NONE; return NS_STYLE_HINT_VISUAL; diff --git a/dom/public/idl/css/nsIDOMCSS2Properties.idl b/dom/public/idl/css/nsIDOMCSS2Properties.idl index 568a3389c2a..886e3c26c04 100644 --- a/dom/public/idl/css/nsIDOMCSS2Properties.idl +++ b/dom/public/idl/css/nsIDOMCSS2Properties.idl @@ -417,6 +417,12 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties attribute DOMString MozAppearance; // raises(DOMException) on setting + attribute DOMString MozBackgroundClip; + // raises(DOMException) on setting + + attribute DOMString MozBackgroundOrigin; + // raises(DOMException) on setting + attribute DOMString MozBinding; // raises(DOMException) on setting diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 46fee54c13c..2e6d09507a3 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -2264,14 +2264,16 @@ void nsCSSRendering::PaintBorderEdges(nsIPresContext* aPresContext, // i.e., they are either 0 or a negative number whose absolute value is // less than the tile size in that dimension // -// aRelativeBounds is the box to which the tiling position should be relative, -// aTilingBounds is the box in which the tiling will actually be done. They -// should be identical except when painting on the canvas, in which case the -// relative bounds should be the bounds of the root element's frame and the -// tiling bounds should be the bounds of the canvas frame. +// aOriginBounds is the box to which the tiling position should be relative +// aClipBounds is the box in which the tiling will actually be done +// They should correspond to 'background-origin' and 'background-clip', +// except when painting on the canvas, in which case the origin bounds +// should be the bounds of the root element's frame and the clip bounds +// should be the bounds of the canvas frame. static void ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, - const nsRect& aRelativeBounds, const nsRect& aTilingBounds, + const nsRect& aOriginBounds, + const nsRect& aClipBounds, nscoord aTileWidth, nscoord aTileHeight, nsPoint& aResult) { @@ -2283,10 +2285,10 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, nscoord t = aColor.mBackgroundXPosition; float pct = float(t) / 100.0f; nscoord tilePos = nscoord(pct * aTileWidth); - nscoord boxPos = nscoord(pct * aRelativeBounds.width); + nscoord boxPos = nscoord(pct * aOriginBounds.width); x = boxPos - tilePos; } - x += aRelativeBounds.x - aTilingBounds.x; + x += aOriginBounds.x - aClipBounds.x; if (NS_STYLE_BG_REPEAT_X & aColor.mBackgroundRepeat) { // When we are tiling in the x direction the loop will run from // the left edge of the box to the right edge of the box. We need @@ -2320,10 +2322,10 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, nscoord t = aColor.mBackgroundYPosition; float pct = float(t) / 100.0f; nscoord tilePos = nscoord(pct * aTileHeight); - nscoord boxPos = nscoord(pct * aRelativeBounds.height); + nscoord boxPos = nscoord(pct * aOriginBounds.height); y = boxPos - tilePos; } - y += aRelativeBounds.y - aTilingBounds.y; + y += aOriginBounds.y - aClipBounds.y; if (NS_STYLE_BG_REPEAT_Y & aColor.mBackgroundRepeat) { // When we are tiling in the y direction the loop will run from // the top edge of the box to the bottom edge of the box. We need @@ -2586,6 +2588,7 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, const nsRect& aDirtyRect, const nsRect& aBorderArea, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY,PRBool aUsePrintSettings) { @@ -2622,7 +2625,8 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, } if (!isCanvas) { PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, - aDirtyRect, aBorderArea, *color, aBorder, aDX, aDY, aUsePrintSettings); + aDirtyRect, aBorderArea, *color, aBorder, + aPadding, aDX, aDY, aUsePrintSettings); return; } @@ -2663,7 +2667,7 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, aDirtyRect, aBorderArea, canvasColor, - aBorder, aDX, aDY, aUsePrintSettings); + aBorder, aPadding, aDX, aDY, aUsePrintSettings); } void @@ -2674,6 +2678,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, const nsRect& aBorderArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings) @@ -2706,144 +2711,99 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, } } - PRBool transparentBG = - NS_STYLE_BG_COLOR_TRANSPARENT == - (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT); - float percent; - nsStyleCoord bordStyleRadius[4]; - PRInt16 borderRadii[4],i; + // The background is rendered over the 'background-clip' area. + nsRect bgClipArea(aBorderArea); + if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) { + NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING, + "unknown background-clip value"); + nsMargin border; + aBorder.GetBorder(border); + bgClipArea.Deflate(border); + } + + // The actual dirty rect is the intersection of the 'background-clip' + // area and the dirty rect we were given + nsRect dirtyRect; + if (!dirtyRect.IntersectRect(bgClipArea, aDirtyRect)) { + // Nothing to paint + return; + } // if there is no background image or background images are turned off, try a color. if (aColor.mBackgroundImage.IsEmpty() || (canDrawBackgroundColor && !canDrawBackgroundImage)) { - // See if there's a background color specified. The background color - // is rendered over the 'border' 'padding' and 'content' areas - if (!transparentBG) { - // get the radius for our border - aBorder.mBorderRadius.GetTop(bordStyleRadius[0]); //topleft - aBorder.mBorderRadius.GetRight(bordStyleRadius[1]); //topright - aBorder.mBorderRadius.GetBottom(bordStyleRadius[2]); //bottomright - aBorder.mBorderRadius.GetLeft(bordStyleRadius[3]); //bottomleft + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + return; + } - for(i=0;i<4;i++) { - borderRadii[i] = 0; - switch ( bordStyleRadius[i].GetUnit()) { - case eStyleUnit_Inherit: - break; - case eStyleUnit_Percent: - percent = bordStyleRadius[i].GetPercentValue(); - borderRadii[i] = (nscoord)(percent * aBorderArea.width); - break; - case eStyleUnit_Coord: - borderRadii[i] = bordStyleRadius[i].GetCoordValue(); - break; - default: - break; - } - } + // We have a background image - // rounded version of the border - if (!aBorder.mBorderColors) { - // XXXdwh Composite borders (with multiple colors per side) use their own border radius - // algorithm now, since the current one doesn't work right for small radii. - for(i=0;i<4;i++){ - if (borderRadii[i] > 0){ - PaintRoundedBackground(aPresContext,aRenderingContext,aForFrame,aDirtyRect, - aBorderArea,aColor,aDX,aDY,borderRadii); - return; - } - } - } - else { - nsMargin border; - aBorder.GetBorder(border); - nsRect borderArea(aBorderArea); - borderArea.Deflate(border); - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(borderArea); - return; - } + // get the frame for the background image load to complete in + // - this may be different than the frame we are rendering + // (as in the case of the canvas frame) + nsIFrame *pBGFrame = nsnull; + GetFrameForBackgroundUpdate(aPresContext, aForFrame, &pBGFrame); + NS_ASSERTION(pBGFrame, "Background Frame must be set by GetFrameForBackgroundUpdate"); - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } - } else { - // we have a background image + // Lookup the image + nsCOMPtr req; + nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req)); + PRUint32 status = imgIRequest::STATUS_ERROR; + if (req) + req->GetImageStatus(&status); - // get the frame for the background image load to complete in - // - this may be different than the frame we are rendering - // (as in the case of the canvas frame) - nsIFrame *pBGFrame = nsnull; - GetFrameForBackgroundUpdate(aPresContext, aForFrame, &pBGFrame); - NS_ASSERTION(pBGFrame, "Background Frame must be set by GetFrameForBackgroundUpdate"); + if (NS_FAILED(rv) || !req || !(status & imgIRequest::STATUS_FRAME_COMPLETE) || !(status & imgIRequest::STATUS_SIZE_AVAILABLE)) { + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + return; + } - // Lookup the image - nsCOMPtr req; - nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req)); + nsCOMPtr image; + req->GetImage(getter_AddRefs(image)); - PRUint32 status = imgIRequest::STATUS_ERROR; - if (req) - req->GetImageStatus(&status); + nsSize imageSize; + image->GetWidth(&imageSize.width); + image->GetHeight(&imageSize.height); - if (NS_FAILED(rv) || !req || !(status & imgIRequest::STATUS_FRAME_COMPLETE) || !(status & imgIRequest::STATUS_SIZE_AVAILABLE)) { - if (!transparentBG) { - // The background color is rendered over the 'border' 'padding' and - // 'content' areas - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } - return; - } + float p2t; + aPresContext->GetPixelsToTwips(&p2t); + imageSize.width = NSIntPixelsToTwips(imageSize.width, p2t); + imageSize.height = NSIntPixelsToTwips(imageSize.height, p2t); - nsSize imageSize; - nsCOMPtr image; - req->GetImage(getter_AddRefs(image)); - - image->GetWidth(&imageSize.width); - image->GetHeight(&imageSize.height); - - float p2t; - aPresContext->GetPixelsToTwips(&p2t); - imageSize.width = NSIntPixelsToTwips(imageSize.width, p2t); - imageSize.height = NSIntPixelsToTwips(imageSize.height, p2t); - - req = nsnull; - - // Background images are tiled over the 'content' and 'padding' areas - // only (not the 'border' area) - nsRect paddingArea(aBorderArea); - nsMargin border; + req = nsnull; + // Background images are tiled over the 'background-clip' area + // but the origin of the tiling is based on the 'background-origin' area + nsRect bgOriginArea(aBorderArea); + if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_BORDER) { + nsMargin border; if (!aBorder.GetBorder(border)) { NS_NOTYETIMPLEMENTED("percentage border"); } - paddingArea.Deflate(border); - // The actual dirty rect is the intersection of the padding area and the - // dirty rect we were given - nsRect dirtyRect; - - if (!dirtyRect.IntersectRect(paddingArea, aDirtyRect)) { - // Nothing to paint - return; + bgOriginArea.Deflate(border); + if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_PADDING) { + nsMargin padding; + // XXX CalcPaddingFor is deprecated, but we need it for percentage padding + aPadding.CalcPaddingFor(aForFrame, padding); + bgOriginArea.Deflate(padding); + NS_ASSERTION(aColor.mBackgroundOrigin == NS_STYLE_BG_ORIGIN_CONTENT, + "unknown background-origin value"); } + } - // Based on the repeat setting, compute how many tiles we should - // lay down for each axis. The value computed is the maximum based - // on the dirty rect before accounting for the background-position. - nscoord tileWidth = imageSize.width; - nscoord tileHeight = imageSize.height; - PRBool needBackgroundColor = PR_TRUE; - PRIntn repeat = aColor.mBackgroundRepeat; - nscoord xDistance, yDistance; - PRBool needBackgroundOnContinuation = PR_FALSE; // set to true if repeat-y value is set + // Based on the repeat setting, compute how many tiles we should + // lay down for each axis. The value computed is the maximum based + // on the dirty rect before accounting for the background-position. + nscoord tileWidth = imageSize.width; + nscoord tileHeight = imageSize.height; + PRBool needBackgroundColor = PR_TRUE; + PRIntn repeat = aColor.mBackgroundRepeat; + nscoord xDistance, yDistance; + PRBool needBackgroundOnContinuation = PR_FALSE; // set to true if repeat-y value is set - switch (repeat) { - case NS_STYLE_BG_REPEAT_OFF: - default: - xDistance = tileWidth; - yDistance = tileHeight; - break; + switch (repeat) { case NS_STYLE_BG_REPEAT_X: xDistance = dirtyRect.width; yDistance = tileHeight; @@ -2860,157 +2820,156 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, // We need to render the background color if the image is transparent //needBackgroundColor = image->GetHasAlphaMask(); break; - } + case NS_STYLE_BG_REPEAT_OFF: + default: + NS_ASSERTION(repeat == NS_STYLE_BG_REPEAT_OFF, "unknown background-repeat value"); + xDistance = tileWidth; + yDistance = tileHeight; + break; + } - // The background color is rendered over the 'border' 'padding' and - // 'content' areas - if (!transparentBG && needBackgroundColor) { - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } + // The background color is rendered over the 'background-clip' area + if (needBackgroundColor) { + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + } - // See if there's nothing left to do - if ((tileWidth == 0) || (tileHeight == 0) || dirtyRect.IsEmpty()) { - // Nothing to paint - return; - } + if ((tileWidth == 0) || (tileHeight == 0) || dirtyRect.IsEmpty()) { + // Nothing left to paint + return; + } - // if the frame is a continuation frame, check if we need to draw the image for it - // (continuation with no repeat setting in the Y direction do not get background images) - if (aForFrame) { - nsIFrame *prevInFlowFrame = nsnull; - aForFrame->GetPrevInFlow(&prevInFlowFrame); - if (prevInFlowFrame != nsnull) { - if (!needBackgroundOnContinuation) { - // the frame is a continuation, and we do not want the background image repeated - // in the Y direction (needBackgroundOnContinuation == PR_FALSE) so just bail - return; + // if the frame is a continuation frame, check if we need to draw the image for it + // (continuation with no repeat setting in the Y direction do not get background images) + if (aForFrame) { + nsIFrame *prevInFlowFrame = nsnull; + aForFrame->GetPrevInFlow(&prevInFlowFrame); + if (prevInFlowFrame) { + if (!needBackgroundOnContinuation) { + // the frame is a continuation, and we do not want the background image repeated + // in the Y direction (needBackgroundOnContinuation == PR_FALSE) so just bail + return; + } + } + } + + + // Compute the anchor point. + // + // When tiling, the anchor coordinate values will be negative offsets + // from the padding area + + nsPoint anchor; + if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { + // If it's a fixed background attachment, then the image is placed + // relative to the nearest scrolling ancestor, or the viewport if + // the frame doesn't have a scrolling ancestor + nsIFrame* scrolledFrame = nsnull; + nsIView* viewportView = nsnull; + nsRect viewportArea; + + // get the nsIScrollableFrame interface from the scrollFrame + nsIFrame* scrollFrame = GetNearestScrollFrame(aForFrame); + if (scrollFrame) { + nsCOMPtr scrollableFrame(do_QueryInterface(scrollFrame)); + if (scrollableFrame) { + scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame); + if (scrolledFrame) { + scrolledFrame->GetRect(viewportArea); + scrolledFrame->GetView(aPresContext, &viewportView); } } } + if (!scrolledFrame) { + // The viewport isn't scrollable, so use the root frame's view + nsCOMPtr presShell; + aPresContext->GetShell(getter_AddRefs(presShell)); + NS_ASSERTION(presShell, "no pres shell"); + nsIFrame* rootFrame; + presShell->GetRootFrame(&rootFrame); + NS_ASSERTION(rootFrame, "no root frame"); - // Compute the anchor point. - // - // When tiling, the anchor coordinate values will be negative offsets - // from the padding area + rootFrame->GetView(aPresContext, &viewportView); + NS_ASSERTION(viewportView, "no viewport view"); + viewportView->GetBounds(viewportArea); + viewportArea.x = 0; + viewportArea.y = 0; + } - nsPoint anchor; - if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { - // If it's a fixed background attachment, then the image is placed - // relative to the nearest scrolling ancestor, or the viewport if - // the frame doesn't have a scrolling ancestor - nsIFrame* scrolledFrame = nsnull; - nsIView* viewportView = nsnull; - nsRect viewportArea; - - // get the nsIScrollableFrame interface from the scrollFrame - nsIFrame* scrollFrame = GetNearestScrollFrame(aForFrame); - if (scrollFrame) { - nsCOMPtr scrollableFrame(do_QueryInterface(scrollFrame)); - if (scrollableFrame) { - scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame); - if (scrolledFrame) { - scrolledFrame->GetRect(viewportArea); - scrolledFrame->GetView(aPresContext, &viewportView); - } - } - } - if (!scrolledFrame) { - // The viewport isn't scrollable, so use the root frame's view - nsCOMPtr presShell; - aPresContext->GetShell(getter_AddRefs(presShell)); - NS_ASSERTION(presShell, "no pres shell"); - - nsIFrame* rootFrame; - presShell->GetRootFrame(&rootFrame); - NS_ASSERTION(rootFrame, "no root frame"); + // Get the anchor point + ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor); - rootFrame->GetView(aPresContext, &viewportView); - NS_ASSERTION(viewportView, "no viewport view"); - viewportView->GetBounds(viewportArea); - viewportArea.x = 0; - viewportArea.y = 0; - } + // Convert the anchor point to aForFrame's coordinate space + nsIView* view; + aForFrame->GetView(aPresContext, &view); + if (!view) { + nsPoint offset; + aForFrame->GetOffsetFromView(aPresContext, offset, &view); + anchor -= offset; + } + NS_ASSERTION(view, "expected a view"); + while (view && (view != viewportView)) { + nscoord x, y; - // Get the anchor point - ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor); + view->GetPosition(&x, &y); + anchor.x -= x; + anchor.y -= y; - // Convert the anchor point to aForFrame's coordinate space - nsIView* view; - aForFrame->GetView(aPresContext, &view); - if (!view) { - nsPoint offset; - aForFrame->GetOffsetFromView(aPresContext, offset, &view); - anchor -= offset; - } - NS_ASSERTION(view, "expected a view"); - while (view && (view != viewportView)) { - nscoord x, y; - - view->GetPosition(&x, &y); - anchor.x -= x; - anchor.y -= y; - - // Get the parent view until we reach the viewport view - view->GetParent(view); - } + // Get the parent view until we reach the viewport view + view->GetParent(view); + } + } else { + nsCOMPtr frameType; + aForFrame->GetFrameType(getter_AddRefs(frameType)); + if (frameType.get() == nsLayoutAtoms::canvasFrame) { + // If the frame is the canvas, the image is placed relative to + // the root element's (first) frame (see bug 46446) + nsRect firstRootElementFrameArea; + nsIFrame* firstRootElementFrame; + aForFrame->FirstChild(aPresContext, nsnull, &firstRootElementFrame); + NS_ASSERTION(firstRootElementFrame, "A canvas with a background " + "image had no child frame, which is impossible according to CSS. " + "Make sure there isn't a background image specified on the " + "|:viewport| pseudo-element in |html.css|."); - // Move the padding area so that we can use the same logic for both the - // fixed and scrolling cases - paddingArea.x = 0; - paddingArea.y = 0; - } else { - nsCOMPtr frameType; - aForFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() == nsLayoutAtoms::canvasFrame) { - // If the frame is the canvas, the image is placed relative to - // the root element's (first) frame (see bug 46446) - nsRect firstRootElementFrameArea; - nsIFrame* firstRootElementFrame; - aForFrame->FirstChild(aPresContext, nsnull, &firstRootElementFrame); - NS_ASSERTION(firstRootElementFrame, "A canvas with a background " - "image had no child frame, which is impossible according to CSS. " - "Make sure there isn't a background image specified on the " - "|:viewport| pseudo-element in |html.css|."); + // temporary null check -- see bug 97226 + if (firstRootElementFrame) { + firstRootElementFrame->GetRect(firstRootElementFrameArea); - // temporary null check -- see bug 97226 - if (firstRootElementFrame) { - firstRootElementFrame->GetRect(firstRootElementFrameArea); + // Take the border out of the frame's rect + const nsStyleBorder* borderStyle; + firstRootElementFrame->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderStyle); + nsMargin border; + borderStyle->GetBorder(border); + firstRootElementFrameArea.Deflate(border); - // Take the border out of the frame's rect - const nsStyleBorder* borderStyle; - firstRootElementFrame->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderStyle); - nsMargin border; - borderStyle->GetBorder(border); - firstRootElementFrameArea.Deflate(border); - - // Get the anchor point - ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, paddingArea, tileWidth, tileHeight, anchor); - } else { - ComputeBackgroundAnchorPoint(aColor, paddingArea, paddingArea, tileWidth, tileHeight, anchor); - } + // Get the anchor point + ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, bgClipArea, tileWidth, tileHeight, anchor); } else { - // Otherwise, it is the normal case, and the background is - // simply placed relative to the frame's padding area - ComputeBackgroundAnchorPoint(aColor, paddingArea, paddingArea, tileWidth, tileHeight, anchor); + ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor); } + } else { + // Otherwise, it is the normal case, and the background is + // simply placed relative to the frame's background-clip area + ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor); } + } #if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) - // Setup clipping so that rendering doesn't leak out of the computed - // dirty rect - PRBool clipState; - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(dirtyRect, nsClipCombine_kIntersect, - clipState); + // Setup clipping so that rendering doesn't leak out of the computed + // dirty rect + PRBool clipState; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(dirtyRect, nsClipCombine_kIntersect, + clipState); #endif - // Compute the x and y starting points and limits for tiling + // Compute the x and y starting points and limits for tiling + + /* An Overview Of The Following Logic - /* An Overview Of The Following Logic - A........ . . . . . . . . . . . . . . : +---:-------.-------.-------.---- /|\ : | : . . . | nh @@ -3024,10 +2983,9 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, . | . . . . |<-----nw------>| |<--w-->| - ---- = the paddingArea edge. The padding is done relative to this - area. Outside the padding is the border. If the background - is positioned relative to the viewport ('fixed') then this - is the viewport edge. + ---- = the background clip area edge. The painting is done within + to this area. If the background is positioned relative to the + viewport ('fixed') then this is the viewport edge. .... = the primary tile. @@ -3056,26 +3014,26 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, Therefore, - x0 = paddingArea.x + anchor.x + n * tileWidth; + x0 = bgClipArea.x + anchor.x + n * tileWidth; ...where n is an integer greater or equal to 0 fitting: n * tileWidth <= - dirtyRect.x - (paddingArea.x + anchor.x) <= + dirtyRect.x - (bgClipArea.x + anchor.x) <= (n+1) * tileWidth ...i.e., - n <= (dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth < n + 1 + n <= (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth < n + 1 ...which, treating the division as an integer divide rounding down, gives: - n = (dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth + n = (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth Substituting into the original expression for x0: - x0 = paddingArea.x + anchor.x + - ((dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth) * + x0 = bgClipArea.x + anchor.x + + ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) * tileWidth; From this x1 is determined, @@ -3103,62 +3061,136 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, tileWidth) * tileWidth The vertical case is analogous. If the background is fixed, then - paddingArea.x and paddingArea.y are set to zero when finding the parent + bgClipArea.x and bgClipArea.y are set to zero when finding the parent viewport, above. - */ + */ - // first do the horizontal case - nscoord x0, x1; - if (repeat & NS_STYLE_BG_REPEAT_X) { - // When tiling in the x direction, adjust the starting position of the - // tile to account for dirtyRect.x. When tiling in x, the anchor.x value - // will be a negative value used to adjust the starting coordinate. - x0 = paddingArea.x + anchor.x + ((dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth) * tileWidth; - x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth) * tileWidth; + // first do the horizontal case + nscoord x0, x1; + if (repeat & NS_STYLE_BG_REPEAT_X) { + // When tiling in the x direction, adjust the starting position of the + // tile to account for dirtyRect.x. When tiling in x, the anchor.x value + // will be a negative value used to adjust the starting coordinate. + x0 = bgClipArea.x + anchor.x + ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) * tileWidth; + x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth) * tileWidth; + } + else { + // For scrolling attachment, the anchor is within the 'background-clip' + // For fixed attachment, the anchor is within the bounds of the nearest + // scrolling ancestor (or the viewport) + x0 = anchor.x; + if (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) { + x0 += bgClipArea.x; } - else { - // For scrolling attachment, the anchor is relative to the padding area. - // For fixed attachment, paddingArea.x is set to zero and the anchor is - // relative to the nearest scrolling ancestor (or the viewport). - x0 = paddingArea.x + anchor.x; - x1 = x0 + tileWidth; - } - - // now do all that again with the vertical case - nscoord y0, y1; - if (repeat & NS_STYLE_BG_REPEAT_Y) { - // When tiling in the y direction, adjust the starting position of the - // tile to account for dirtyRect.y. When tiling in y, the anchor.y value - // will be a negative value used to adjust the starting coordinate. - y0 = paddingArea.y + anchor.y + ((dirtyRect.y - (paddingArea.y + anchor.y)) / tileHeight) * tileHeight; - y1 = y0 + ((dirtyRect.y + dirtyRect.height - y0 + tileHeight - 1) / tileHeight) * tileHeight; - } - else { - // For scrolling attachment, the anchor is relative to the padding area. - // For fixed attachment, paddingArea.y is set to zero and the anchor is - // relative to the nearest scrolling ancestor (or the viewport). - y0 = paddingArea.y + anchor.y; - y1 = y0 + tileHeight; - } - - // Take the intersection again to paint only the required area - nsRect tileRect(x0,y0,(x1-x0),(y1-y0)); - nsRect drawRect; - - if (drawRect.IntersectRect(tileRect, dirtyRect)) { - PRInt32 xOffset = drawRect.x - x0, - yOffset = drawRect.y - y0; - aRenderingContext.DrawTile(image,xOffset,yOffset,&drawRect); - } - -#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) - // Restore clipping - aRenderingContext.PopState(clipState); -#endif - + x1 = x0 + tileWidth; } + // now do all that again with the vertical case + nscoord y0, y1; + if (repeat & NS_STYLE_BG_REPEAT_Y) { + // When tiling in the y direction, adjust the starting position of the + // tile to account for dirtyRect.y. When tiling in y, the anchor.y value + // will be a negative value used to adjust the starting coordinate. + y0 = bgClipArea.y + anchor.y + ((dirtyRect.y - (bgClipArea.y + anchor.y)) / tileHeight) * tileHeight; + y1 = y0 + ((dirtyRect.y + dirtyRect.height - y0 + tileHeight - 1) / tileHeight) * tileHeight; + } + else { + // For scrolling attachment, the anchor is within the 'background-clip' + // For fixed attachment, the anchor is within the bounds of the nearest + // scrolling ancestor (or the viewport) + y0 = anchor.y; + if (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) { + y0 += bgClipArea.y; + } + y1 = y0 + tileHeight; + } + + // Take the intersection again to paint only the required area + nsRect tileRect(x0, y0, (x1 - x0), (y1 - y0)); + nsRect drawRect; + + if (drawRect.IntersectRect(tileRect, dirtyRect)) { + PRInt32 xOffset = drawRect.x - x0, + yOffset = drawRect.y - y0; + aRenderingContext.DrawTile(image, xOffset, yOffset, &drawRect); + } + +#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) + // Restore clipping + aRenderingContext.PopState(clipState); +#endif + +} + +void +nsCSSRendering::PaintBackgroundColor(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, + nscoord aDX, + nscoord aDY) +{ + if (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { + // nothing to paint + return; + } + + nsStyleCoord bordStyleRadius[4]; + PRInt16 borderRadii[4]; + nsRect bgClipArea(aBgClipArea); + + // get the radius for our border + aBorder.mBorderRadius.GetTop(bordStyleRadius[NS_SIDE_TOP]); // topleft + aBorder.mBorderRadius.GetRight(bordStyleRadius[NS_SIDE_RIGHT]); // topright + aBorder.mBorderRadius.GetBottom(bordStyleRadius[NS_SIDE_BOTTOM]); // bottomright + aBorder.mBorderRadius.GetLeft(bordStyleRadius[NS_SIDE_LEFT]); // bottomleft + + PRUint8 side = 0; + for (; side < 4; ++side) { + borderRadii[side] = 0; + switch (bordStyleRadius[side].GetUnit()) { + case eStyleUnit_Inherit: + // do nothing + break; + case eStyleUnit_Percent: + borderRadii[side] = nscoord(bordStyleRadius[side].GetPercentValue() * aBgClipArea.width); + break; + case eStyleUnit_Coord: + borderRadii[side] = bordStyleRadius[side].GetCoordValue(); + break; + default: + break; + } + } + + // Rounded version of the border + // XXXdwh Composite borders (with multiple colors per side) use their own border radius + // algorithm now, since the current one doesn't work right for small radii. + if (!aBorder.mBorderColors) { + for (side = 0; side < 4; ++side) { + if (borderRadii[side] > 0) { + PaintRoundedBackground(aPresContext, aRenderingContext, aForFrame, + bgClipArea, aColor, aBorder, aDX, aDY, borderRadii); + return; + } + } + } + else if (aColor.mBackgroundClip == NS_STYLE_BG_CLIP_BORDER) { + // XXX users of -moz-border-*-colors expect a transparent border-color + // to show the parent's background-color instead of its background-color. + // This seems wrong, but we handle that here by explictly clipping the + // background to the padding area. + nsMargin border; + aBorder.GetBorder(border); + bgClipArea.Deflate(border); + } + + aRenderingContext.SetColor(aColor.mBackgroundColor); + aRenderingContext.FillRect(bgClipArea); } /** --------------------------------------------------- @@ -3199,24 +3231,24 @@ PRInt32 flag = NS_COPYBITS_TO_BACK_BUFFER | NS_COPYBITS_XFORM_DEST_VALUES; */ void nsCSSRendering::PaintRoundedBackground(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - const nsStyleBackground& aColor, - nscoord aDX, - nscoord aDY, - PRInt16 aTheRadius[4]) + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + nscoord aDX, + nscoord aDY, + PRInt16 aTheRadius[4]) { -RoundedRect outerPath; -QBCurve cr1,cr2,cr3,cr4; -QBCurve UL,UR,LL,LR; -PRInt32 curIndex,c1Index; -nsFloatPoint thePath[MAXPATHSIZE]; -static nsPoint polyPath[MAXPOLYPATHSIZE]; -PRInt16 np; -nscoord twipsPerPixel; -float p2t; + RoundedRect outerPath; + QBCurve cr1,cr2,cr3,cr4; + QBCurve UL,UR,LL,LR; + PRInt32 curIndex,c1Index; + nsFloatPoint thePath[MAXPATHSIZE]; + static nsPoint polyPath[MAXPOLYPATHSIZE]; + PRInt16 np; + nscoord twipsPerPixel; + float p2t; // needed for our border thickness aPresContext->GetPixelsToTwips(&p2t); @@ -3224,8 +3256,27 @@ float p2t; aRenderingContext.SetColor(aColor.mBackgroundColor); + // Adjust for background-clip, if necessary + if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) { + NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING, "unknown background-clip value"); + + // Get the radius to the outer edge of the padding. + // -moz-border-radius is the radius to the outer edge of the border. + nsMargin border; + aBorder.GetBorder(border); + aTheRadius[NS_SIDE_TOP] -= border.top; + aTheRadius[NS_SIDE_RIGHT] -= border.right; + aTheRadius[NS_SIDE_BOTTOM] -= border.bottom; + aTheRadius[NS_SIDE_LEFT] -= border.left; + for (PRUint8 i = 0; i < 4; ++i) { + if (aTheRadius[i] < 0) { + aTheRadius[i] = 0; + } + } + } + // set the rounded rect up, and let'er rip - outerPath.Set(aBorderArea.x,aBorderArea.y,aBorderArea.width,aBorderArea.height,aTheRadius,twipsPerPixel); + outerPath.Set(aBgClipArea.x,aBgClipArea.y,aBgClipArea.width,aBgClipArea.height,aTheRadius,twipsPerPixel); outerPath.GetRoundedBorders(UL,UR,LL,LR); // BUILD THE ENTIRE OUTSIDE PATH @@ -3278,7 +3329,6 @@ float p2t; GetPath(thePath,polyPath,&curIndex,eOutside,c1Index); aRenderingContext.FillPolygon(polyPath,curIndex); - } diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index ef80f4c4336..ef9be35158a 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -139,6 +139,7 @@ public: const nsRect& aDirtyRect, const nsRect& aBorderArea, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); @@ -155,6 +156,7 @@ public: const nsRect& aBorderArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); @@ -229,22 +231,30 @@ protected: PRInt16 aBorderRadius[4],nsRect* aGap = 0, PRBool aIsOutline=PR_FALSE); - static void RenderSide(nsFloatPoint aPoints[],nsIRenderingContext& aRenderingContext, const nsStyleBorder* aBorderStyle,const nsStyleOutline* aOutlineStyle,nsIStyleContext* aStyleContext, PRUint8 aSide,nsMargin &aBorThick,nscoord aTwipsPerPixel, PRBool aIsOutline=PR_FALSE); - static void PaintRoundedBackground(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - const nsStyleBackground& aColor, - nscoord aDX, - nscoord aDY, - PRInt16 aTheRadius[4]); + static void PaintBackgroundColor(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, + nscoord aDX, + nscoord aDY); + static void PaintRoundedBackground(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBorderArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + nscoord aDX, + nscoord aDY, + PRInt16 aTheRadius[4]); static nscolor MakeBevelColor(PRIntn whichSide, PRUint8 style, nscolor aBackgroundColor, diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index 447c66d9fb1..b4a258a315b 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -188,16 +188,16 @@ #define NS_STYLE_VOLUME_LOUD 4 #define NS_STYLE_VOLUME_X_LOUD 5 -// See nsStyleColor -#define NS_STYLE_BG_ATTACHMENT_SCROLL 0 -#define NS_STYLE_BG_ATTACHMENT_FIXED 1 - // See nsStyleColor #define NS_STYLE_COLOR_TRANSPARENT 0 #define NS_STYLE_COLOR_INVERT 1 #define NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR 2 // See nsStyleColor +#define NS_COLOR_MOZ_HYPERLINKTEXT -1 +#define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT -2 + +// See nsStyleBackground #define NS_STYLE_BG_COLOR_TRANSPARENT 0x01 #define NS_STYLE_BG_IMAGE_NONE 0x02 #define NS_STYLE_BG_X_POSITION_PERCENT 0x04 @@ -205,16 +205,25 @@ #define NS_STYLE_BG_Y_POSITION_PERCENT 0x10 #define NS_STYLE_BG_Y_POSITION_LENGTH 0x20 -// See nsStyleColor +// See nsStyleBackground +#define NS_STYLE_BG_ATTACHMENT_SCROLL 0 +#define NS_STYLE_BG_ATTACHMENT_FIXED 1 + +// See nsStyleBackground +#define NS_STYLE_BG_CLIP_BORDER 0 +#define NS_STYLE_BG_CLIP_PADDING 1 + +// See nsStyleBackground +#define NS_STYLE_BG_ORIGIN_BORDER 0 +#define NS_STYLE_BG_ORIGIN_PADDING 1 +#define NS_STYLE_BG_ORIGIN_CONTENT 2 + +// See nsStyleBackground #define NS_STYLE_BG_REPEAT_OFF 0x00 #define NS_STYLE_BG_REPEAT_X 0x01 #define NS_STYLE_BG_REPEAT_Y 0x02 #define NS_STYLE_BG_REPEAT_XY 0x03 -// See nsStyleColor -#define NS_COLOR_MOZ_HYPERLINKTEXT -1 -#define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT -2 - // See nsStyleTable #define NS_STYLE_BORDER_COLLAPSE 0 #define NS_STYLE_BORDER_SEPARATE 1 diff --git a/layout/base/public/nsStyleConsts.h b/layout/base/public/nsStyleConsts.h index 447c66d9fb1..b4a258a315b 100644 --- a/layout/base/public/nsStyleConsts.h +++ b/layout/base/public/nsStyleConsts.h @@ -188,16 +188,16 @@ #define NS_STYLE_VOLUME_LOUD 4 #define NS_STYLE_VOLUME_X_LOUD 5 -// See nsStyleColor -#define NS_STYLE_BG_ATTACHMENT_SCROLL 0 -#define NS_STYLE_BG_ATTACHMENT_FIXED 1 - // See nsStyleColor #define NS_STYLE_COLOR_TRANSPARENT 0 #define NS_STYLE_COLOR_INVERT 1 #define NS_STYLE_COLOR_MOZ_USE_TEXT_COLOR 2 // See nsStyleColor +#define NS_COLOR_MOZ_HYPERLINKTEXT -1 +#define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT -2 + +// See nsStyleBackground #define NS_STYLE_BG_COLOR_TRANSPARENT 0x01 #define NS_STYLE_BG_IMAGE_NONE 0x02 #define NS_STYLE_BG_X_POSITION_PERCENT 0x04 @@ -205,16 +205,25 @@ #define NS_STYLE_BG_Y_POSITION_PERCENT 0x10 #define NS_STYLE_BG_Y_POSITION_LENGTH 0x20 -// See nsStyleColor +// See nsStyleBackground +#define NS_STYLE_BG_ATTACHMENT_SCROLL 0 +#define NS_STYLE_BG_ATTACHMENT_FIXED 1 + +// See nsStyleBackground +#define NS_STYLE_BG_CLIP_BORDER 0 +#define NS_STYLE_BG_CLIP_PADDING 1 + +// See nsStyleBackground +#define NS_STYLE_BG_ORIGIN_BORDER 0 +#define NS_STYLE_BG_ORIGIN_PADDING 1 +#define NS_STYLE_BG_ORIGIN_CONTENT 2 + +// See nsStyleBackground #define NS_STYLE_BG_REPEAT_OFF 0x00 #define NS_STYLE_BG_REPEAT_X 0x01 #define NS_STYLE_BG_REPEAT_Y 0x02 #define NS_STYLE_BG_REPEAT_XY 0x03 -// See nsStyleColor -#define NS_COLOR_MOZ_HYPERLINKTEXT -1 -#define NS_COLOR_MOZ_VISITEDHYPERLINKTEXT -2 - // See nsStyleTable #define NS_STYLE_BORDER_COLLAPSE 0 #define NS_STYLE_BORDER_SEPARATE 1 diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 3efa0ad742f..9f8cf2d928c 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -178,9 +178,12 @@ nsButtonFrameRenderer::PaintBorderAndBackground(nsIPresContext* aPresContext, const nsStyleBorder* border = (const nsStyleBorder*)context->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = + (const nsStylePadding*)context->GetStyleData(eStyleStruct_Padding); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame, - aDirtyRect, buttonRect, *border, 0, 0); + aDirtyRect, buttonRect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, aDirtyRect, buttonRect, *border, context, 0); } diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index bb9e84aa760..4c44bb728f8 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -187,6 +187,8 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* borderStyle = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* paddingStyle = + (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsMargin border; if (!borderStyle->GetBorder(border)) { @@ -203,7 +205,8 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, nsRect rect(0, yoff, mRect.width, mRect.height - yoff); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *borderStyle, 0, 0); + aDirtyRect, rect, *borderStyle, + *paddingStyle, 0, 0); if (mLegendFrame) { diff --git a/layout/forms/nsGfxCheckboxControlFrame.cpp b/layout/forms/nsGfxCheckboxControlFrame.cpp index 7c63a6ed733..fc22d39fb2e 100644 --- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -246,6 +246,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, if (myColor->mBackgroundImage.Length() > 0) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Padding); const nsStylePosition* myPosition = (const nsStylePosition*) mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Position); @@ -257,7 +259,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, nsRect rect(x, y, width, height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mCheckButtonFaceStyle, 0); doDefaultPainting = PR_FALSE; diff --git a/layout/forms/nsGfxRadioControlFrame.cpp b/layout/forms/nsGfxRadioControlFrame.cpp index 4d845c31df8..90d2775d157 100644 --- a/layout/forms/nsGfxRadioControlFrame.cpp +++ b/layout/forms/nsGfxRadioControlFrame.cpp @@ -201,6 +201,8 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, const nsStyleBorder* myBorder = (const nsStyleBorder*) mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Padding); const nsStylePosition* myPosition = (const nsStylePosition*) mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Position); @@ -211,7 +213,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, nscoord y = (mRect.height - height) / 2; nsRect rect(x, y, width, height); - // So we will use the PaintBackground to paint the dot, + // So we will use PaintBackgroundWithSC to paint the dot, // but it uses the mBackgroundColor for painting and we need to use the mColor // so create a temporary style color struct and set it up appropriately // XXXldb It would make more sense to use @@ -221,7 +223,8 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, tmpColor.mBackgroundColor = color->mColor; nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, this, aDirtyRect, rect, - tmpColor, *myBorder, 0, 0); + tmpColor, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mRadioButtonFaceStyle, 0); } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 8e176380944..8dd711c92bf 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -5657,13 +5657,16 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); // Paint background, border and outline nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index 44e73d6f2d8..b1f9226d302 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -87,12 +87,15 @@ nsHTMLContainerFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 1700c913f7e..b24737bb4f6 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1295,9 +1295,12 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, if (vis->IsVisibleOrCollapsed()) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mStyleContext, 0); diff --git a/layout/generic/nsLeafFrame.cpp b/layout/generic/nsLeafFrame.cpp index 636bf4cc979..e06dc7787ee 100644 --- a/layout/generic/nsLeafFrame.cpp +++ b/layout/generic/nsLeafFrame.cpp @@ -68,11 +68,14 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext, if (vis->IsVisibleOrCollapsed()) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* myOutline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mStyleContext, 0); diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index dad8726455e..538ce8436b1 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -748,11 +748,16 @@ nsPageFrame::DrawBackground(nsIPresContext* aPresContext, nsRect rect; pageContentFrame->GetRect(rect); - const nsStyleBorder* border = NS_STATIC_CAST(const nsStyleBorder*, - mStyleContext->GetStyleData(eStyleStruct_Border)); + const nsStyleBorder* border = + NS_STATIC_CAST(const nsStyleBorder*, + mStyleContext->GetStyleData(eStyleStruct_Border)); + const nsStylePadding* padding = + NS_STATIC_CAST(const nsStylePadding*, + mStyleContext->GetStyleData(eStyleStruct_Padding)); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0, PR_TRUE); + aDirtyRect, rect, *border, *padding, + 0, 0, PR_TRUE); } } diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index 8e176380944..8dd711c92bf 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -5657,13 +5657,16 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); // Paint background, border and outline nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); diff --git a/layout/html/base/src/nsHRFrame.cpp b/layout/html/base/src/nsHRFrame.cpp index 8e4124ea414..909f391aa00 100644 --- a/layout/html/base/src/nsHRFrame.cpp +++ b/layout/html/base/src/nsHRFrame.cpp @@ -194,10 +194,11 @@ HRuleFrame::Paint(nsIPresContext* aPresContext, nsRect rect(x0, y0, width, height); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) mStyleContext->GetStyleData(eStyleStruct_Padding); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,aDirtyRect, rect, - *border, 0, 0); + *border, *padding, 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,aDirtyRect, rect, *border, mStyleContext, 0); diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp index 44e73d6f2d8..b1f9226d302 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -87,12 +87,15 @@ nsHTMLContainerFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); diff --git a/layout/html/base/src/nsImageFrame.cpp b/layout/html/base/src/nsImageFrame.cpp index 1700c913f7e..b24737bb4f6 100644 --- a/layout/html/base/src/nsImageFrame.cpp +++ b/layout/html/base/src/nsImageFrame.cpp @@ -1295,9 +1295,12 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, if (vis->IsVisibleOrCollapsed()) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mStyleContext, 0); diff --git a/layout/html/base/src/nsLeafFrame.cpp b/layout/html/base/src/nsLeafFrame.cpp index 636bf4cc979..e06dc7787ee 100644 --- a/layout/html/base/src/nsLeafFrame.cpp +++ b/layout/html/base/src/nsLeafFrame.cpp @@ -68,11 +68,14 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext, if (vis->IsVisibleOrCollapsed()) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* myOutline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mStyleContext, 0); diff --git a/layout/html/base/src/nsPageFrame.cpp b/layout/html/base/src/nsPageFrame.cpp index dad8726455e..538ce8436b1 100644 --- a/layout/html/base/src/nsPageFrame.cpp +++ b/layout/html/base/src/nsPageFrame.cpp @@ -748,11 +748,16 @@ nsPageFrame::DrawBackground(nsIPresContext* aPresContext, nsRect rect; pageContentFrame->GetRect(rect); - const nsStyleBorder* border = NS_STATIC_CAST(const nsStyleBorder*, - mStyleContext->GetStyleData(eStyleStruct_Border)); + const nsStyleBorder* border = + NS_STATIC_CAST(const nsStyleBorder*, + mStyleContext->GetStyleData(eStyleStruct_Border)); + const nsStylePadding* padding = + NS_STATIC_CAST(const nsStylePadding*, + mStyleContext->GetStyleData(eStyleStruct_Padding)); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0, PR_TRUE); + aDirtyRect, rect, *border, *padding, + 0, 0, PR_TRUE); } } diff --git a/layout/html/forms/src/nsButtonFrameRenderer.cpp b/layout/html/forms/src/nsButtonFrameRenderer.cpp index 3efa0ad742f..9f8cf2d928c 100644 --- a/layout/html/forms/src/nsButtonFrameRenderer.cpp +++ b/layout/html/forms/src/nsButtonFrameRenderer.cpp @@ -178,9 +178,12 @@ nsButtonFrameRenderer::PaintBorderAndBackground(nsIPresContext* aPresContext, const nsStyleBorder* border = (const nsStyleBorder*)context->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = + (const nsStylePadding*)context->GetStyleData(eStyleStruct_Padding); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame, - aDirtyRect, buttonRect, *border, 0, 0); + aDirtyRect, buttonRect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, aDirtyRect, buttonRect, *border, context, 0); } diff --git a/layout/html/forms/src/nsFieldSetFrame.cpp b/layout/html/forms/src/nsFieldSetFrame.cpp index bb9e84aa760..4c44bb728f8 100644 --- a/layout/html/forms/src/nsFieldSetFrame.cpp +++ b/layout/html/forms/src/nsFieldSetFrame.cpp @@ -187,6 +187,8 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* borderStyle = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* paddingStyle = + (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsMargin border; if (!borderStyle->GetBorder(border)) { @@ -203,7 +205,8 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, nsRect rect(0, yoff, mRect.width, mRect.height - yoff); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *borderStyle, 0, 0); + aDirtyRect, rect, *borderStyle, + *paddingStyle, 0, 0); if (mLegendFrame) { diff --git a/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp b/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp index 7c63a6ed733..fc22d39fb2e 100644 --- a/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp +++ b/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp @@ -246,6 +246,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, if (myColor->mBackgroundImage.Length() > 0) { const nsStyleBorder* myBorder = (const nsStyleBorder*) mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Padding); const nsStylePosition* myPosition = (const nsStylePosition*) mCheckButtonFaceStyle->GetStyleData(eStyleStruct_Position); @@ -257,7 +259,8 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, nsRect rect(x, y, width, height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mCheckButtonFaceStyle, 0); doDefaultPainting = PR_FALSE; diff --git a/layout/html/forms/src/nsGfxRadioControlFrame.cpp b/layout/html/forms/src/nsGfxRadioControlFrame.cpp index 4d845c31df8..90d2775d157 100644 --- a/layout/html/forms/src/nsGfxRadioControlFrame.cpp +++ b/layout/html/forms/src/nsGfxRadioControlFrame.cpp @@ -201,6 +201,8 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, const nsStyleBorder* myBorder = (const nsStyleBorder*) mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Padding); const nsStylePosition* myPosition = (const nsStylePosition*) mRadioButtonFaceStyle->GetStyleData(eStyleStruct_Position); @@ -211,7 +213,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, nscoord y = (mRect.height - height) / 2; nsRect rect(x, y, width, height); - // So we will use the PaintBackground to paint the dot, + // So we will use PaintBackgroundWithSC to paint the dot, // but it uses the mBackgroundColor for painting and we need to use the mColor // so create a temporary style color struct and set it up appropriately // XXXldb It would make more sense to use @@ -221,7 +223,8 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext, tmpColor.mBackgroundColor = color->mColor; nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, this, aDirtyRect, rect, - tmpColor, *myBorder, 0, 0); + tmpColor, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, mRadioButtonFaceStyle, 0); } diff --git a/layout/html/style/src/nsCSSRendering.cpp b/layout/html/style/src/nsCSSRendering.cpp index 46fee54c13c..2e6d09507a3 100644 --- a/layout/html/style/src/nsCSSRendering.cpp +++ b/layout/html/style/src/nsCSSRendering.cpp @@ -2264,14 +2264,16 @@ void nsCSSRendering::PaintBorderEdges(nsIPresContext* aPresContext, // i.e., they are either 0 or a negative number whose absolute value is // less than the tile size in that dimension // -// aRelativeBounds is the box to which the tiling position should be relative, -// aTilingBounds is the box in which the tiling will actually be done. They -// should be identical except when painting on the canvas, in which case the -// relative bounds should be the bounds of the root element's frame and the -// tiling bounds should be the bounds of the canvas frame. +// aOriginBounds is the box to which the tiling position should be relative +// aClipBounds is the box in which the tiling will actually be done +// They should correspond to 'background-origin' and 'background-clip', +// except when painting on the canvas, in which case the origin bounds +// should be the bounds of the root element's frame and the clip bounds +// should be the bounds of the canvas frame. static void ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, - const nsRect& aRelativeBounds, const nsRect& aTilingBounds, + const nsRect& aOriginBounds, + const nsRect& aClipBounds, nscoord aTileWidth, nscoord aTileHeight, nsPoint& aResult) { @@ -2283,10 +2285,10 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, nscoord t = aColor.mBackgroundXPosition; float pct = float(t) / 100.0f; nscoord tilePos = nscoord(pct * aTileWidth); - nscoord boxPos = nscoord(pct * aRelativeBounds.width); + nscoord boxPos = nscoord(pct * aOriginBounds.width); x = boxPos - tilePos; } - x += aRelativeBounds.x - aTilingBounds.x; + x += aOriginBounds.x - aClipBounds.x; if (NS_STYLE_BG_REPEAT_X & aColor.mBackgroundRepeat) { // When we are tiling in the x direction the loop will run from // the left edge of the box to the right edge of the box. We need @@ -2320,10 +2322,10 @@ ComputeBackgroundAnchorPoint(const nsStyleBackground& aColor, nscoord t = aColor.mBackgroundYPosition; float pct = float(t) / 100.0f; nscoord tilePos = nscoord(pct * aTileHeight); - nscoord boxPos = nscoord(pct * aRelativeBounds.height); + nscoord boxPos = nscoord(pct * aOriginBounds.height); y = boxPos - tilePos; } - y += aRelativeBounds.y - aTilingBounds.y; + y += aOriginBounds.y - aClipBounds.y; if (NS_STYLE_BG_REPEAT_Y & aColor.mBackgroundRepeat) { // When we are tiling in the y direction the loop will run from // the top edge of the box to the bottom edge of the box. We need @@ -2586,6 +2588,7 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, const nsRect& aDirtyRect, const nsRect& aBorderArea, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY,PRBool aUsePrintSettings) { @@ -2622,7 +2625,8 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, } if (!isCanvas) { PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, - aDirtyRect, aBorderArea, *color, aBorder, aDX, aDY, aUsePrintSettings); + aDirtyRect, aBorderArea, *color, aBorder, + aPadding, aDX, aDY, aUsePrintSettings); return; } @@ -2663,7 +2667,7 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, aDirtyRect, aBorderArea, canvasColor, - aBorder, aDX, aDY, aUsePrintSettings); + aBorder, aPadding, aDX, aDY, aUsePrintSettings); } void @@ -2674,6 +2678,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, const nsRect& aBorderArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings) @@ -2706,144 +2711,99 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, } } - PRBool transparentBG = - NS_STYLE_BG_COLOR_TRANSPARENT == - (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT); - float percent; - nsStyleCoord bordStyleRadius[4]; - PRInt16 borderRadii[4],i; + // The background is rendered over the 'background-clip' area. + nsRect bgClipArea(aBorderArea); + if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) { + NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING, + "unknown background-clip value"); + nsMargin border; + aBorder.GetBorder(border); + bgClipArea.Deflate(border); + } + + // The actual dirty rect is the intersection of the 'background-clip' + // area and the dirty rect we were given + nsRect dirtyRect; + if (!dirtyRect.IntersectRect(bgClipArea, aDirtyRect)) { + // Nothing to paint + return; + } // if there is no background image or background images are turned off, try a color. if (aColor.mBackgroundImage.IsEmpty() || (canDrawBackgroundColor && !canDrawBackgroundImage)) { - // See if there's a background color specified. The background color - // is rendered over the 'border' 'padding' and 'content' areas - if (!transparentBG) { - // get the radius for our border - aBorder.mBorderRadius.GetTop(bordStyleRadius[0]); //topleft - aBorder.mBorderRadius.GetRight(bordStyleRadius[1]); //topright - aBorder.mBorderRadius.GetBottom(bordStyleRadius[2]); //bottomright - aBorder.mBorderRadius.GetLeft(bordStyleRadius[3]); //bottomleft + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + return; + } - for(i=0;i<4;i++) { - borderRadii[i] = 0; - switch ( bordStyleRadius[i].GetUnit()) { - case eStyleUnit_Inherit: - break; - case eStyleUnit_Percent: - percent = bordStyleRadius[i].GetPercentValue(); - borderRadii[i] = (nscoord)(percent * aBorderArea.width); - break; - case eStyleUnit_Coord: - borderRadii[i] = bordStyleRadius[i].GetCoordValue(); - break; - default: - break; - } - } + // We have a background image - // rounded version of the border - if (!aBorder.mBorderColors) { - // XXXdwh Composite borders (with multiple colors per side) use their own border radius - // algorithm now, since the current one doesn't work right for small radii. - for(i=0;i<4;i++){ - if (borderRadii[i] > 0){ - PaintRoundedBackground(aPresContext,aRenderingContext,aForFrame,aDirtyRect, - aBorderArea,aColor,aDX,aDY,borderRadii); - return; - } - } - } - else { - nsMargin border; - aBorder.GetBorder(border); - nsRect borderArea(aBorderArea); - borderArea.Deflate(border); - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(borderArea); - return; - } + // get the frame for the background image load to complete in + // - this may be different than the frame we are rendering + // (as in the case of the canvas frame) + nsIFrame *pBGFrame = nsnull; + GetFrameForBackgroundUpdate(aPresContext, aForFrame, &pBGFrame); + NS_ASSERTION(pBGFrame, "Background Frame must be set by GetFrameForBackgroundUpdate"); - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } - } else { - // we have a background image + // Lookup the image + nsCOMPtr req; + nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req)); + PRUint32 status = imgIRequest::STATUS_ERROR; + if (req) + req->GetImageStatus(&status); - // get the frame for the background image load to complete in - // - this may be different than the frame we are rendering - // (as in the case of the canvas frame) - nsIFrame *pBGFrame = nsnull; - GetFrameForBackgroundUpdate(aPresContext, aForFrame, &pBGFrame); - NS_ASSERTION(pBGFrame, "Background Frame must be set by GetFrameForBackgroundUpdate"); + if (NS_FAILED(rv) || !req || !(status & imgIRequest::STATUS_FRAME_COMPLETE) || !(status & imgIRequest::STATUS_SIZE_AVAILABLE)) { + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + return; + } - // Lookup the image - nsCOMPtr req; - nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req)); + nsCOMPtr image; + req->GetImage(getter_AddRefs(image)); - PRUint32 status = imgIRequest::STATUS_ERROR; - if (req) - req->GetImageStatus(&status); + nsSize imageSize; + image->GetWidth(&imageSize.width); + image->GetHeight(&imageSize.height); - if (NS_FAILED(rv) || !req || !(status & imgIRequest::STATUS_FRAME_COMPLETE) || !(status & imgIRequest::STATUS_SIZE_AVAILABLE)) { - if (!transparentBG) { - // The background color is rendered over the 'border' 'padding' and - // 'content' areas - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } - return; - } + float p2t; + aPresContext->GetPixelsToTwips(&p2t); + imageSize.width = NSIntPixelsToTwips(imageSize.width, p2t); + imageSize.height = NSIntPixelsToTwips(imageSize.height, p2t); - nsSize imageSize; - nsCOMPtr image; - req->GetImage(getter_AddRefs(image)); - - image->GetWidth(&imageSize.width); - image->GetHeight(&imageSize.height); - - float p2t; - aPresContext->GetPixelsToTwips(&p2t); - imageSize.width = NSIntPixelsToTwips(imageSize.width, p2t); - imageSize.height = NSIntPixelsToTwips(imageSize.height, p2t); - - req = nsnull; - - // Background images are tiled over the 'content' and 'padding' areas - // only (not the 'border' area) - nsRect paddingArea(aBorderArea); - nsMargin border; + req = nsnull; + // Background images are tiled over the 'background-clip' area + // but the origin of the tiling is based on the 'background-origin' area + nsRect bgOriginArea(aBorderArea); + if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_BORDER) { + nsMargin border; if (!aBorder.GetBorder(border)) { NS_NOTYETIMPLEMENTED("percentage border"); } - paddingArea.Deflate(border); - // The actual dirty rect is the intersection of the padding area and the - // dirty rect we were given - nsRect dirtyRect; - - if (!dirtyRect.IntersectRect(paddingArea, aDirtyRect)) { - // Nothing to paint - return; + bgOriginArea.Deflate(border); + if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_PADDING) { + nsMargin padding; + // XXX CalcPaddingFor is deprecated, but we need it for percentage padding + aPadding.CalcPaddingFor(aForFrame, padding); + bgOriginArea.Deflate(padding); + NS_ASSERTION(aColor.mBackgroundOrigin == NS_STYLE_BG_ORIGIN_CONTENT, + "unknown background-origin value"); } + } - // Based on the repeat setting, compute how many tiles we should - // lay down for each axis. The value computed is the maximum based - // on the dirty rect before accounting for the background-position. - nscoord tileWidth = imageSize.width; - nscoord tileHeight = imageSize.height; - PRBool needBackgroundColor = PR_TRUE; - PRIntn repeat = aColor.mBackgroundRepeat; - nscoord xDistance, yDistance; - PRBool needBackgroundOnContinuation = PR_FALSE; // set to true if repeat-y value is set + // Based on the repeat setting, compute how many tiles we should + // lay down for each axis. The value computed is the maximum based + // on the dirty rect before accounting for the background-position. + nscoord tileWidth = imageSize.width; + nscoord tileHeight = imageSize.height; + PRBool needBackgroundColor = PR_TRUE; + PRIntn repeat = aColor.mBackgroundRepeat; + nscoord xDistance, yDistance; + PRBool needBackgroundOnContinuation = PR_FALSE; // set to true if repeat-y value is set - switch (repeat) { - case NS_STYLE_BG_REPEAT_OFF: - default: - xDistance = tileWidth; - yDistance = tileHeight; - break; + switch (repeat) { case NS_STYLE_BG_REPEAT_X: xDistance = dirtyRect.width; yDistance = tileHeight; @@ -2860,157 +2820,156 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, // We need to render the background color if the image is transparent //needBackgroundColor = image->GetHasAlphaMask(); break; - } + case NS_STYLE_BG_REPEAT_OFF: + default: + NS_ASSERTION(repeat == NS_STYLE_BG_REPEAT_OFF, "unknown background-repeat value"); + xDistance = tileWidth; + yDistance = tileHeight; + break; + } - // The background color is rendered over the 'border' 'padding' and - // 'content' areas - if (!transparentBG && needBackgroundColor) { - aRenderingContext.SetColor(aColor.mBackgroundColor); - aRenderingContext.FillRect(aBorderArea); - } + // The background color is rendered over the 'background-clip' area + if (needBackgroundColor) { + PaintBackgroundColor(aPresContext, aRenderingContext, aForFrame, bgClipArea, + aColor, aBorder, aPadding, aDX, aDY); + } - // See if there's nothing left to do - if ((tileWidth == 0) || (tileHeight == 0) || dirtyRect.IsEmpty()) { - // Nothing to paint - return; - } + if ((tileWidth == 0) || (tileHeight == 0) || dirtyRect.IsEmpty()) { + // Nothing left to paint + return; + } - // if the frame is a continuation frame, check if we need to draw the image for it - // (continuation with no repeat setting in the Y direction do not get background images) - if (aForFrame) { - nsIFrame *prevInFlowFrame = nsnull; - aForFrame->GetPrevInFlow(&prevInFlowFrame); - if (prevInFlowFrame != nsnull) { - if (!needBackgroundOnContinuation) { - // the frame is a continuation, and we do not want the background image repeated - // in the Y direction (needBackgroundOnContinuation == PR_FALSE) so just bail - return; + // if the frame is a continuation frame, check if we need to draw the image for it + // (continuation with no repeat setting in the Y direction do not get background images) + if (aForFrame) { + nsIFrame *prevInFlowFrame = nsnull; + aForFrame->GetPrevInFlow(&prevInFlowFrame); + if (prevInFlowFrame) { + if (!needBackgroundOnContinuation) { + // the frame is a continuation, and we do not want the background image repeated + // in the Y direction (needBackgroundOnContinuation == PR_FALSE) so just bail + return; + } + } + } + + + // Compute the anchor point. + // + // When tiling, the anchor coordinate values will be negative offsets + // from the padding area + + nsPoint anchor; + if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { + // If it's a fixed background attachment, then the image is placed + // relative to the nearest scrolling ancestor, or the viewport if + // the frame doesn't have a scrolling ancestor + nsIFrame* scrolledFrame = nsnull; + nsIView* viewportView = nsnull; + nsRect viewportArea; + + // get the nsIScrollableFrame interface from the scrollFrame + nsIFrame* scrollFrame = GetNearestScrollFrame(aForFrame); + if (scrollFrame) { + nsCOMPtr scrollableFrame(do_QueryInterface(scrollFrame)); + if (scrollableFrame) { + scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame); + if (scrolledFrame) { + scrolledFrame->GetRect(viewportArea); + scrolledFrame->GetView(aPresContext, &viewportView); } } } + if (!scrolledFrame) { + // The viewport isn't scrollable, so use the root frame's view + nsCOMPtr presShell; + aPresContext->GetShell(getter_AddRefs(presShell)); + NS_ASSERTION(presShell, "no pres shell"); + nsIFrame* rootFrame; + presShell->GetRootFrame(&rootFrame); + NS_ASSERTION(rootFrame, "no root frame"); - // Compute the anchor point. - // - // When tiling, the anchor coordinate values will be negative offsets - // from the padding area + rootFrame->GetView(aPresContext, &viewportView); + NS_ASSERTION(viewportView, "no viewport view"); + viewportView->GetBounds(viewportArea); + viewportArea.x = 0; + viewportArea.y = 0; + } - nsPoint anchor; - if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { - // If it's a fixed background attachment, then the image is placed - // relative to the nearest scrolling ancestor, or the viewport if - // the frame doesn't have a scrolling ancestor - nsIFrame* scrolledFrame = nsnull; - nsIView* viewportView = nsnull; - nsRect viewportArea; - - // get the nsIScrollableFrame interface from the scrollFrame - nsIFrame* scrollFrame = GetNearestScrollFrame(aForFrame); - if (scrollFrame) { - nsCOMPtr scrollableFrame(do_QueryInterface(scrollFrame)); - if (scrollableFrame) { - scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame); - if (scrolledFrame) { - scrolledFrame->GetRect(viewportArea); - scrolledFrame->GetView(aPresContext, &viewportView); - } - } - } - if (!scrolledFrame) { - // The viewport isn't scrollable, so use the root frame's view - nsCOMPtr presShell; - aPresContext->GetShell(getter_AddRefs(presShell)); - NS_ASSERTION(presShell, "no pres shell"); - - nsIFrame* rootFrame; - presShell->GetRootFrame(&rootFrame); - NS_ASSERTION(rootFrame, "no root frame"); + // Get the anchor point + ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor); - rootFrame->GetView(aPresContext, &viewportView); - NS_ASSERTION(viewportView, "no viewport view"); - viewportView->GetBounds(viewportArea); - viewportArea.x = 0; - viewportArea.y = 0; - } + // Convert the anchor point to aForFrame's coordinate space + nsIView* view; + aForFrame->GetView(aPresContext, &view); + if (!view) { + nsPoint offset; + aForFrame->GetOffsetFromView(aPresContext, offset, &view); + anchor -= offset; + } + NS_ASSERTION(view, "expected a view"); + while (view && (view != viewportView)) { + nscoord x, y; - // Get the anchor point - ComputeBackgroundAnchorPoint(aColor, viewportArea, viewportArea, tileWidth, tileHeight, anchor); + view->GetPosition(&x, &y); + anchor.x -= x; + anchor.y -= y; - // Convert the anchor point to aForFrame's coordinate space - nsIView* view; - aForFrame->GetView(aPresContext, &view); - if (!view) { - nsPoint offset; - aForFrame->GetOffsetFromView(aPresContext, offset, &view); - anchor -= offset; - } - NS_ASSERTION(view, "expected a view"); - while (view && (view != viewportView)) { - nscoord x, y; - - view->GetPosition(&x, &y); - anchor.x -= x; - anchor.y -= y; - - // Get the parent view until we reach the viewport view - view->GetParent(view); - } + // Get the parent view until we reach the viewport view + view->GetParent(view); + } + } else { + nsCOMPtr frameType; + aForFrame->GetFrameType(getter_AddRefs(frameType)); + if (frameType.get() == nsLayoutAtoms::canvasFrame) { + // If the frame is the canvas, the image is placed relative to + // the root element's (first) frame (see bug 46446) + nsRect firstRootElementFrameArea; + nsIFrame* firstRootElementFrame; + aForFrame->FirstChild(aPresContext, nsnull, &firstRootElementFrame); + NS_ASSERTION(firstRootElementFrame, "A canvas with a background " + "image had no child frame, which is impossible according to CSS. " + "Make sure there isn't a background image specified on the " + "|:viewport| pseudo-element in |html.css|."); - // Move the padding area so that we can use the same logic for both the - // fixed and scrolling cases - paddingArea.x = 0; - paddingArea.y = 0; - } else { - nsCOMPtr frameType; - aForFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() == nsLayoutAtoms::canvasFrame) { - // If the frame is the canvas, the image is placed relative to - // the root element's (first) frame (see bug 46446) - nsRect firstRootElementFrameArea; - nsIFrame* firstRootElementFrame; - aForFrame->FirstChild(aPresContext, nsnull, &firstRootElementFrame); - NS_ASSERTION(firstRootElementFrame, "A canvas with a background " - "image had no child frame, which is impossible according to CSS. " - "Make sure there isn't a background image specified on the " - "|:viewport| pseudo-element in |html.css|."); + // temporary null check -- see bug 97226 + if (firstRootElementFrame) { + firstRootElementFrame->GetRect(firstRootElementFrameArea); - // temporary null check -- see bug 97226 - if (firstRootElementFrame) { - firstRootElementFrame->GetRect(firstRootElementFrameArea); + // Take the border out of the frame's rect + const nsStyleBorder* borderStyle; + firstRootElementFrame->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderStyle); + nsMargin border; + borderStyle->GetBorder(border); + firstRootElementFrameArea.Deflate(border); - // Take the border out of the frame's rect - const nsStyleBorder* borderStyle; - firstRootElementFrame->GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderStyle); - nsMargin border; - borderStyle->GetBorder(border); - firstRootElementFrameArea.Deflate(border); - - // Get the anchor point - ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, paddingArea, tileWidth, tileHeight, anchor); - } else { - ComputeBackgroundAnchorPoint(aColor, paddingArea, paddingArea, tileWidth, tileHeight, anchor); - } + // Get the anchor point + ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, bgClipArea, tileWidth, tileHeight, anchor); } else { - // Otherwise, it is the normal case, and the background is - // simply placed relative to the frame's padding area - ComputeBackgroundAnchorPoint(aColor, paddingArea, paddingArea, tileWidth, tileHeight, anchor); + ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor); } + } else { + // Otherwise, it is the normal case, and the background is + // simply placed relative to the frame's background-clip area + ComputeBackgroundAnchorPoint(aColor, bgOriginArea, bgClipArea, tileWidth, tileHeight, anchor); } + } #if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) - // Setup clipping so that rendering doesn't leak out of the computed - // dirty rect - PRBool clipState; - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(dirtyRect, nsClipCombine_kIntersect, - clipState); + // Setup clipping so that rendering doesn't leak out of the computed + // dirty rect + PRBool clipState; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(dirtyRect, nsClipCombine_kIntersect, + clipState); #endif - // Compute the x and y starting points and limits for tiling + // Compute the x and y starting points and limits for tiling + + /* An Overview Of The Following Logic - /* An Overview Of The Following Logic - A........ . . . . . . . . . . . . . . : +---:-------.-------.-------.---- /|\ : | : . . . | nh @@ -3024,10 +2983,9 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, . | . . . . |<-----nw------>| |<--w-->| - ---- = the paddingArea edge. The padding is done relative to this - area. Outside the padding is the border. If the background - is positioned relative to the viewport ('fixed') then this - is the viewport edge. + ---- = the background clip area edge. The painting is done within + to this area. If the background is positioned relative to the + viewport ('fixed') then this is the viewport edge. .... = the primary tile. @@ -3056,26 +3014,26 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, Therefore, - x0 = paddingArea.x + anchor.x + n * tileWidth; + x0 = bgClipArea.x + anchor.x + n * tileWidth; ...where n is an integer greater or equal to 0 fitting: n * tileWidth <= - dirtyRect.x - (paddingArea.x + anchor.x) <= + dirtyRect.x - (bgClipArea.x + anchor.x) <= (n+1) * tileWidth ...i.e., - n <= (dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth < n + 1 + n <= (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth < n + 1 ...which, treating the division as an integer divide rounding down, gives: - n = (dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth + n = (dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth Substituting into the original expression for x0: - x0 = paddingArea.x + anchor.x + - ((dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth) * + x0 = bgClipArea.x + anchor.x + + ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) * tileWidth; From this x1 is determined, @@ -3103,62 +3061,136 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, tileWidth) * tileWidth The vertical case is analogous. If the background is fixed, then - paddingArea.x and paddingArea.y are set to zero when finding the parent + bgClipArea.x and bgClipArea.y are set to zero when finding the parent viewport, above. - */ + */ - // first do the horizontal case - nscoord x0, x1; - if (repeat & NS_STYLE_BG_REPEAT_X) { - // When tiling in the x direction, adjust the starting position of the - // tile to account for dirtyRect.x. When tiling in x, the anchor.x value - // will be a negative value used to adjust the starting coordinate. - x0 = paddingArea.x + anchor.x + ((dirtyRect.x - (paddingArea.x + anchor.x)) / tileWidth) * tileWidth; - x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth) * tileWidth; + // first do the horizontal case + nscoord x0, x1; + if (repeat & NS_STYLE_BG_REPEAT_X) { + // When tiling in the x direction, adjust the starting position of the + // tile to account for dirtyRect.x. When tiling in x, the anchor.x value + // will be a negative value used to adjust the starting coordinate. + x0 = bgClipArea.x + anchor.x + ((dirtyRect.x - (bgClipArea.x + anchor.x)) / tileWidth) * tileWidth; + x1 = x0 + ((dirtyRect.x + dirtyRect.width - x0 + tileWidth - 1) / tileWidth) * tileWidth; + } + else { + // For scrolling attachment, the anchor is within the 'background-clip' + // For fixed attachment, the anchor is within the bounds of the nearest + // scrolling ancestor (or the viewport) + x0 = anchor.x; + if (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) { + x0 += bgClipArea.x; } - else { - // For scrolling attachment, the anchor is relative to the padding area. - // For fixed attachment, paddingArea.x is set to zero and the anchor is - // relative to the nearest scrolling ancestor (or the viewport). - x0 = paddingArea.x + anchor.x; - x1 = x0 + tileWidth; - } - - // now do all that again with the vertical case - nscoord y0, y1; - if (repeat & NS_STYLE_BG_REPEAT_Y) { - // When tiling in the y direction, adjust the starting position of the - // tile to account for dirtyRect.y. When tiling in y, the anchor.y value - // will be a negative value used to adjust the starting coordinate. - y0 = paddingArea.y + anchor.y + ((dirtyRect.y - (paddingArea.y + anchor.y)) / tileHeight) * tileHeight; - y1 = y0 + ((dirtyRect.y + dirtyRect.height - y0 + tileHeight - 1) / tileHeight) * tileHeight; - } - else { - // For scrolling attachment, the anchor is relative to the padding area. - // For fixed attachment, paddingArea.y is set to zero and the anchor is - // relative to the nearest scrolling ancestor (or the viewport). - y0 = paddingArea.y + anchor.y; - y1 = y0 + tileHeight; - } - - // Take the intersection again to paint only the required area - nsRect tileRect(x0,y0,(x1-x0),(y1-y0)); - nsRect drawRect; - - if (drawRect.IntersectRect(tileRect, dirtyRect)) { - PRInt32 xOffset = drawRect.x - x0, - yOffset = drawRect.y - y0; - aRenderingContext.DrawTile(image,xOffset,yOffset,&drawRect); - } - -#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) - // Restore clipping - aRenderingContext.PopState(clipState); -#endif - + x1 = x0 + tileWidth; } + // now do all that again with the vertical case + nscoord y0, y1; + if (repeat & NS_STYLE_BG_REPEAT_Y) { + // When tiling in the y direction, adjust the starting position of the + // tile to account for dirtyRect.y. When tiling in y, the anchor.y value + // will be a negative value used to adjust the starting coordinate. + y0 = bgClipArea.y + anchor.y + ((dirtyRect.y - (bgClipArea.y + anchor.y)) / tileHeight) * tileHeight; + y1 = y0 + ((dirtyRect.y + dirtyRect.height - y0 + tileHeight - 1) / tileHeight) * tileHeight; + } + else { + // For scrolling attachment, the anchor is within the 'background-clip' + // For fixed attachment, the anchor is within the bounds of the nearest + // scrolling ancestor (or the viewport) + y0 = anchor.y; + if (NS_STYLE_BG_ATTACHMENT_SCROLL == aColor.mBackgroundAttachment) { + y0 += bgClipArea.y; + } + y1 = y0 + tileHeight; + } + + // Take the intersection again to paint only the required area + nsRect tileRect(x0, y0, (x1 - x0), (y1 - y0)); + nsRect drawRect; + + if (drawRect.IntersectRect(tileRect, dirtyRect)) { + PRInt32 xOffset = drawRect.x - x0, + yOffset = drawRect.y - y0; + aRenderingContext.DrawTile(image, xOffset, yOffset, &drawRect); + } + +#if (!defined(XP_UNIX) && !defined(XP_BEOS)) || defined(XP_MACOSX) + // Restore clipping + aRenderingContext.PopState(clipState); +#endif + +} + +void +nsCSSRendering::PaintBackgroundColor(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, + nscoord aDX, + nscoord aDY) +{ + if (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) { + // nothing to paint + return; + } + + nsStyleCoord bordStyleRadius[4]; + PRInt16 borderRadii[4]; + nsRect bgClipArea(aBgClipArea); + + // get the radius for our border + aBorder.mBorderRadius.GetTop(bordStyleRadius[NS_SIDE_TOP]); // topleft + aBorder.mBorderRadius.GetRight(bordStyleRadius[NS_SIDE_RIGHT]); // topright + aBorder.mBorderRadius.GetBottom(bordStyleRadius[NS_SIDE_BOTTOM]); // bottomright + aBorder.mBorderRadius.GetLeft(bordStyleRadius[NS_SIDE_LEFT]); // bottomleft + + PRUint8 side = 0; + for (; side < 4; ++side) { + borderRadii[side] = 0; + switch (bordStyleRadius[side].GetUnit()) { + case eStyleUnit_Inherit: + // do nothing + break; + case eStyleUnit_Percent: + borderRadii[side] = nscoord(bordStyleRadius[side].GetPercentValue() * aBgClipArea.width); + break; + case eStyleUnit_Coord: + borderRadii[side] = bordStyleRadius[side].GetCoordValue(); + break; + default: + break; + } + } + + // Rounded version of the border + // XXXdwh Composite borders (with multiple colors per side) use their own border radius + // algorithm now, since the current one doesn't work right for small radii. + if (!aBorder.mBorderColors) { + for (side = 0; side < 4; ++side) { + if (borderRadii[side] > 0) { + PaintRoundedBackground(aPresContext, aRenderingContext, aForFrame, + bgClipArea, aColor, aBorder, aDX, aDY, borderRadii); + return; + } + } + } + else if (aColor.mBackgroundClip == NS_STYLE_BG_CLIP_BORDER) { + // XXX users of -moz-border-*-colors expect a transparent border-color + // to show the parent's background-color instead of its background-color. + // This seems wrong, but we handle that here by explictly clipping the + // background to the padding area. + nsMargin border; + aBorder.GetBorder(border); + bgClipArea.Deflate(border); + } + + aRenderingContext.SetColor(aColor.mBackgroundColor); + aRenderingContext.FillRect(bgClipArea); } /** --------------------------------------------------- @@ -3199,24 +3231,24 @@ PRInt32 flag = NS_COPYBITS_TO_BACK_BUFFER | NS_COPYBITS_XFORM_DEST_VALUES; */ void nsCSSRendering::PaintRoundedBackground(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - const nsStyleBackground& aColor, - nscoord aDX, - nscoord aDY, - PRInt16 aTheRadius[4]) + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + nscoord aDX, + nscoord aDY, + PRInt16 aTheRadius[4]) { -RoundedRect outerPath; -QBCurve cr1,cr2,cr3,cr4; -QBCurve UL,UR,LL,LR; -PRInt32 curIndex,c1Index; -nsFloatPoint thePath[MAXPATHSIZE]; -static nsPoint polyPath[MAXPOLYPATHSIZE]; -PRInt16 np; -nscoord twipsPerPixel; -float p2t; + RoundedRect outerPath; + QBCurve cr1,cr2,cr3,cr4; + QBCurve UL,UR,LL,LR; + PRInt32 curIndex,c1Index; + nsFloatPoint thePath[MAXPATHSIZE]; + static nsPoint polyPath[MAXPOLYPATHSIZE]; + PRInt16 np; + nscoord twipsPerPixel; + float p2t; // needed for our border thickness aPresContext->GetPixelsToTwips(&p2t); @@ -3224,8 +3256,27 @@ float p2t; aRenderingContext.SetColor(aColor.mBackgroundColor); + // Adjust for background-clip, if necessary + if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) { + NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING, "unknown background-clip value"); + + // Get the radius to the outer edge of the padding. + // -moz-border-radius is the radius to the outer edge of the border. + nsMargin border; + aBorder.GetBorder(border); + aTheRadius[NS_SIDE_TOP] -= border.top; + aTheRadius[NS_SIDE_RIGHT] -= border.right; + aTheRadius[NS_SIDE_BOTTOM] -= border.bottom; + aTheRadius[NS_SIDE_LEFT] -= border.left; + for (PRUint8 i = 0; i < 4; ++i) { + if (aTheRadius[i] < 0) { + aTheRadius[i] = 0; + } + } + } + // set the rounded rect up, and let'er rip - outerPath.Set(aBorderArea.x,aBorderArea.y,aBorderArea.width,aBorderArea.height,aTheRadius,twipsPerPixel); + outerPath.Set(aBgClipArea.x,aBgClipArea.y,aBgClipArea.width,aBgClipArea.height,aTheRadius,twipsPerPixel); outerPath.GetRoundedBorders(UL,UR,LL,LR); // BUILD THE ENTIRE OUTSIDE PATH @@ -3278,7 +3329,6 @@ float p2t; GetPath(thePath,polyPath,&curIndex,eOutside,c1Index); aRenderingContext.FillPolygon(polyPath,curIndex); - } diff --git a/layout/html/style/src/nsCSSRendering.h b/layout/html/style/src/nsCSSRendering.h index ef80f4c4336..ef9be35158a 100644 --- a/layout/html/style/src/nsCSSRendering.h +++ b/layout/html/style/src/nsCSSRendering.h @@ -139,6 +139,7 @@ public: const nsRect& aDirtyRect, const nsRect& aBorderArea, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); @@ -155,6 +156,7 @@ public: const nsRect& aBorderArea, const nsStyleBackground& aColor, const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); @@ -229,22 +231,30 @@ protected: PRInt16 aBorderRadius[4],nsRect* aGap = 0, PRBool aIsOutline=PR_FALSE); - static void RenderSide(nsFloatPoint aPoints[],nsIRenderingContext& aRenderingContext, const nsStyleBorder* aBorderStyle,const nsStyleOutline* aOutlineStyle,nsIStyleContext* aStyleContext, PRUint8 aSide,nsMargin &aBorThick,nscoord aTwipsPerPixel, PRBool aIsOutline=PR_FALSE); - static void PaintRoundedBackground(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsIFrame* aForFrame, - const nsRect& aDirtyRect, - const nsRect& aBorderArea, - const nsStyleBackground& aColor, - nscoord aDX, - nscoord aDY, - PRInt16 aTheRadius[4]); + static void PaintBackgroundColor(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBgClipArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + const nsStylePadding& aPadding, + nscoord aDX, + nscoord aDY); + static void PaintRoundedBackground(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIFrame* aForFrame, + const nsRect& aBorderArea, + const nsStyleBackground& aColor, + const nsStyleBorder& aBorder, + nscoord aDX, + nscoord aDY, + PRInt16 aTheRadius[4]); static nscolor MakeBevelColor(PRIntn whichSide, PRUint8 style, nscolor aBackgroundColor, diff --git a/layout/html/table/src/nsTableCellFrame.cpp b/layout/html/table/src/nsTableCellFrame.cpp index 43087b4ce48..405b16899e0 100644 --- a/layout/html/table/src/nsTableCellFrame.cpp +++ b/layout/html/table/src/nsTableCellFrame.cpp @@ -418,13 +418,15 @@ nsTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren) { if (aVisibleBackground) { nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(&aPresContext, aRenderingContext, this, - aDirtyRect, rect, aStyleBorder, 0, 0, PR_TRUE); + aDirtyRect, rect, aStyleBorder, aStylePadding, + 0, 0, PR_TRUE); // draw the border only when there is content or showing empty cells if (!GetContentEmpty() || NS_STYLE_TABLE_EMPTY_CELLS_SHOW == aCellTableStyle.mEmptyCells) { PRIntn skipSides = GetSkipSides(); @@ -455,11 +457,15 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { PRBool paintBackground = PR_FALSE; const nsStyleBorder* myBorder = nsnull; + const nsStylePadding* myPadding = nsnull; const nsStyleTableBorder* cellTableStyle = nsnull; const nsStyleVisibility* vis = (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility); if (vis->IsVisibleOrCollapsed()) { - myBorder = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); NS_ENSURE_TRUE(myBorder, NS_ERROR_NULL_POINTER); + myBorder = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + NS_ENSURE_TRUE(myBorder, NS_ERROR_NULL_POINTER); + myPadding = (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Border); + NS_ENSURE_TRUE(myPadding, NS_ERROR_NULL_POINTER); GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)cellTableStyle)); @@ -470,7 +476,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, } PaintUnderlay(*aPresContext, aRenderingContext, aDirtyRect, aFlags, *cellTableStyle, - *myBorder, paintBackground, paintChildren); + *myBorder, *myPadding, paintBackground, paintChildren); if (vis->IsVisibleOrCollapsed()) { const nsStyleBackground* myColor = @@ -1537,6 +1543,7 @@ nsBCTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren) { @@ -1561,7 +1568,8 @@ nsBCTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(&aPresContext, aRenderingContext, this, - aDirtyRect, rect, myBorder, 0, 0, PR_TRUE); + aDirtyRect, rect, myBorder, aStylePadding, + 0, 0, PR_TRUE); // borders are painted by nsTableFrame } diff --git a/layout/html/table/src/nsTableCellFrame.h b/layout/html/table/src/nsTableCellFrame.h index e452dcb7599..79c6abdb838 100644 --- a/layout/html/table/src/nsTableCellFrame.h +++ b/layout/html/table/src/nsTableCellFrame.h @@ -302,6 +302,7 @@ protected: PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren); @@ -480,6 +481,7 @@ protected: PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren); diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp index 29bbc301aa4..641ce693d31 100644 --- a/layout/html/table/src/nsTableFrame.cpp +++ b/layout/html/table/src/nsTableFrame.cpp @@ -1463,10 +1463,13 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, if (vis && vis->IsVisibleOrCollapsed()) { const nsStyleBorder* border = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = + (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0, PR_TRUE); + aDirtyRect, rect, *border, *padding, + 0, 0, PR_TRUE); // paint the border here only for separate borders if (!IsBorderCollapse()) { diff --git a/layout/mathml/base/src/nsMathMLChar.cpp b/layout/mathml/base/src/nsMathMLChar.cpp index a6d7ff97557..2289a5fbb7d 100644 --- a/layout/mathml/base/src/nsMathMLChar.cpp +++ b/layout/mathml/base/src/nsMathMLChar.cpp @@ -1901,17 +1901,20 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext, else if (mRect.width && mRect.height) { const nsStyleBorder *border = NS_STATIC_CAST(const nsStyleBorder*, styleContext->GetStyleData(eStyleStruct_Border)); + const nsStylePadding *padding = NS_STATIC_CAST(const nsStylePadding*, + styleContext->GetStyleData(eStyleStruct_Padding)); const nsStyleBackground *backg = NS_STATIC_CAST(const nsStyleBackground*, styleContext->GetStyleData(eStyleStruct_Background)); nsRect rect(mRect); //0, 0, mRect.width, mRect.height); if (styleContext != parentContext.get() && 0 == (backg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)) nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame, - aDirtyRect, rect, *backg, *border, 0, 0); + aDirtyRect, rect, *backg, *border, *padding, + 0, 0); //else // our container frame will take care of painting its background // nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, - // aDirtyRect, rect, *border, 0, 0); + // aDirtyRect, rect, *border, *padding, 0, 0); #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) // for visual debug PRIntn skipSides = 0; //aForFrame->GetSkipSides(); diff --git a/layout/mathml/base/src/nsMathMLmactionFrame.cpp b/layout/mathml/base/src/nsMathMLmactionFrame.cpp index b2c7a90472d..c1963180f36 100644 --- a/layout/mathml/base/src/nsMathMLmactionFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmactionFrame.cpp @@ -269,12 +269,14 @@ nsMathMLmactionFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, diff --git a/layout/style/nsCSSDeclaration.cpp b/layout/style/nsCSSDeclaration.cpp index 02269ec745a..5c9b8f77ea6 100644 --- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -166,7 +166,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackRepeat(aCopy.mBackRepeat), mBackAttachment(aCopy.mBackAttachment), mBackPositionX(aCopy.mBackPositionX), - mBackPositionY(aCopy.mBackPositionY) + mBackPositionY(aCopy.mBackPositionY), + mBackClip(aCopy.mBackClip), + mBackOrigin(aCopy.mBackOrigin) { MOZ_COUNT_CTOR(nsCSSColor); } @@ -195,6 +197,8 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackAttachment.AppendToString(buffer, eCSSProperty_background_attachment); mBackPositionX.AppendToString(buffer, eCSSProperty_background_x_position); mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); + mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); + mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1471,7 +1475,9 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1481,6 +1487,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_attachment: theColor->mBackAttachment = aValue; break; case eCSSProperty_background_x_position: theColor->mBackPositionX = aValue; break; case eCSSProperty_background_y_position: theColor->mBackPositionY = aValue; break; + case eCSSProperty__moz_background_clip: theColor->mBackClip = aValue; break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2310,7 +2318,9 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2322,6 +2332,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) CSS_CASE_IMPORTANT(eCSSProperty_background_attachment, Color, mBackAttachment); CSS_CASE_IMPORTANT(eCSSProperty_background_x_position, Color, mBackPositionX); CSS_CASE_IMPORTANT(eCSSProperty_background_y_position, Color, mBackPositionY); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_clip, Color, mBackClip); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_origin, Color, mBackOrigin); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3272,7 +3284,9 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3282,6 +3296,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_attachment: theColor->mBackAttachment.Reset(); break; case eCSSProperty_background_x_position: theColor->mBackPositionX.Reset(); break; case eCSSProperty_background_y_position: theColor->mBackPositionY.Reset(); break; + case eCSSProperty__moz_background_clip: theColor->mBackClip.Reset(); break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4100,7 +4116,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4111,6 +4129,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_attachment: aValue = theColor->mBackAttachment; break; case eCSSProperty_background_x_position: aValue = theColor->mBackPositionX; break; case eCSSProperty_background_y_position: aValue = theColor->mBackPositionY; break; + case eCSSProperty__moz_background_clip: aValue = theColor->mBackClip; break; + case eCSSProperty__moz_background_origin: aValue = theColor->mBackOrigin; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/layout/style/nsCSSDeclaration.h b/layout/style/nsCSSDeclaration.h index 7f336020995..94f109babf4 100644 --- a/layout/style/nsCSSDeclaration.h +++ b/layout/style/nsCSSDeclaration.h @@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackAttachment; nsCSSValue mBackPositionX; nsCSSValue mBackPositionY; + nsCSSValue mBackClip; + nsCSSValue mBackOrigin; }; struct nsCSSShadow { diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index 3207e2cc6bf..3f762a2d583 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -181,6 +181,7 @@ CSS_KEY(block, block) CSS_KEY(block-axis, block_axis) CSS_KEY(bold, bold) CSS_KEY(bolder, bolder) +CSS_KEY(border, border) CSS_KEY(border-box, border_box) CSS_KEY(both, both) CSS_KEY(bottom, bottom) @@ -203,6 +204,7 @@ CSS_KEY(cm, cm) CSS_KEY(code, code) CSS_KEY(collapse, collapse) CSS_KEY(condensed, condensed) +CSS_KEY(content, content) CSS_KEY(content-box, content_box) CSS_KEY(continuous, continuous) CSS_KEY(crop, crop) @@ -316,6 +318,7 @@ CSS_KEY(open-quote, open_quote) CSS_KEY(outset, outset) CSS_KEY(outside, outside) CSS_KEY(overline, overline) +CSS_KEY(padding, padding) CSS_KEY(padding-box, padding_box) CSS_KEY(pc, pc) CSS_KEY(pointer, pointer) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 79c97fb3860..570057dc024 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -3748,11 +3748,17 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode, case eCSSProperty_background_attachment: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundAttachmentKTable); + case eCSSProperty__moz_background_clip: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundClipKTable); case eCSSProperty_background_color: return ParseVariant(aErrorCode, aValue, VARIANT_HCK, nsCSSProps::kBackgroundColorKTable); case eCSSProperty_background_image: return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull); + case eCSSProperty__moz_background_origin: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundOriginKTable); case eCSSProperty_background_repeat: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundRepeatKTable); @@ -4244,9 +4250,23 @@ PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsCSSDeclaration* aDe } PRInt32 index; - for (index = 0; index < numProps; index++) { + for (index = 0; index < numProps; ++index) { AppendValue(aDeclaration, kBackgroundIDs[index], values[index], aChangeHint); } + + // Background properties not settable from the shorthand get reset to their initial value + const PRInt32 numResetProps = 2; + static const nsCSSProperty kBackgroundResetIDs[numResetProps] = { + eCSSProperty__moz_background_clip, + eCSSProperty__moz_background_origin + }; + + nsCSSValue initial; + initial.SetInitialValue(); + for (index = 0; index < numResetProps; ++index) { + AppendValue(aDeclaration, kBackgroundResetIDs[index], initial, aChangeHint); + } + return PR_TRUE; } diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 32fbaea06d9..7c13710474a 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -109,8 +109,10 @@ CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, MozOu CSS_PROP(azimuth, azimuth, Azimuth, NS_STYLE_HINT_AURAL) CSS_PROP(background, background, Background, NS_STYLE_HINT_VISUAL) CSS_PROP(background-attachment, background_attachment, BackgroundAttachment, NS_STYLE_HINT_FRAMECHANGE) +CSS_PROP(-moz-background-clip, _moz_background_clip, MozBackgroundClip, NS_STYLE_HINT_VISUAL) CSS_PROP(background-color, background_color, BackgroundColor, NS_STYLE_HINT_VISUAL) CSS_PROP(background-image, background_image, BackgroundImage, NS_STYLE_HINT_VISUAL) +CSS_PROP(-moz-background-origin, _moz_background_origin, MozBackgroundOrigin, NS_STYLE_HINT_VISUAL) CSS_PROP(background-position, background_position, BackgroundPosition, NS_STYLE_HINT_VISUAL) CSS_PROP(background-repeat, background_repeat, BackgroundRepeat, NS_STYLE_HINT_VISUAL) CSS_PROP_INTERNAL(-x-background-x-position, background_x_position, BackgroundXPosition, NS_STYLE_HINT_VISUAL) // XXX bug 3935 diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 15fc2a4f6fe..bb4f6d2821c 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -222,6 +222,19 @@ const PRInt32 nsCSSProps::kBackgroundColorKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundClipKTable[] = { + eCSSKeyword_border, NS_STYLE_BG_CLIP_BORDER, + eCSSKeyword_padding, NS_STYLE_BG_CLIP_PADDING, + -1,-1 +}; + +const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = { + eCSSKeyword_border, NS_STYLE_BG_ORIGIN_BORDER, + eCSSKeyword_padding, NS_STYLE_BG_ORIGIN_PADDING, + eCSSKeyword_content, NS_STYLE_BG_ORIGIN_CONTENT, + -1,-1 +}; + const PRInt32 nsCSSProps::kBackgroundRepeatKTable[] = { eCSSKeyword_no_repeat, NS_STYLE_BG_REPEAT_OFF, eCSSKeyword_repeat, NS_STYLE_BG_REPEAT_XY, @@ -920,6 +933,12 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_background_repeat: return SearchKeywordTable(aValue, kBackgroundRepeatKTable); + case eCSSProperty__moz_background_clip: + return SearchKeywordTable(aValue, kBackgroundClipKTable); + + case eCSSProperty__moz_background_origin: + return SearchKeywordTable(aValue, kBackgroundOriginKTable); + case eCSSProperty_background_x_position: return SearchKeywordTable(aValue, kBackgroundXPositionKTable); diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 8b203e993fd..bd77f3ae95b 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -87,7 +87,9 @@ public: static const PRInt32 kAppearanceKTable[]; static const PRInt32 kAzimuthKTable[]; static const PRInt32 kBackgroundAttachmentKTable[]; + static const PRInt32 kBackgroundClipKTable[]; static const PRInt32 kBackgroundColorKTable[]; + static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; static const PRInt32 kBorderCollapseKTable[]; static const PRInt32 kBorderColorKTable[]; diff --git a/layout/style/nsCSSStruct.cpp b/layout/style/nsCSSStruct.cpp index 02269ec745a..5c9b8f77ea6 100644 --- a/layout/style/nsCSSStruct.cpp +++ b/layout/style/nsCSSStruct.cpp @@ -166,7 +166,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackRepeat(aCopy.mBackRepeat), mBackAttachment(aCopy.mBackAttachment), mBackPositionX(aCopy.mBackPositionX), - mBackPositionY(aCopy.mBackPositionY) + mBackPositionY(aCopy.mBackPositionY), + mBackClip(aCopy.mBackClip), + mBackOrigin(aCopy.mBackOrigin) { MOZ_COUNT_CTOR(nsCSSColor); } @@ -195,6 +197,8 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackAttachment.AppendToString(buffer, eCSSProperty_background_attachment); mBackPositionX.AppendToString(buffer, eCSSProperty_background_x_position); mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); + mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); + mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1471,7 +1475,9 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1481,6 +1487,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_attachment: theColor->mBackAttachment = aValue; break; case eCSSProperty_background_x_position: theColor->mBackPositionX = aValue; break; case eCSSProperty_background_y_position: theColor->mBackPositionY = aValue; break; + case eCSSProperty__moz_background_clip: theColor->mBackClip = aValue; break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2310,7 +2318,9 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2322,6 +2332,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) CSS_CASE_IMPORTANT(eCSSProperty_background_attachment, Color, mBackAttachment); CSS_CASE_IMPORTANT(eCSSProperty_background_x_position, Color, mBackPositionX); CSS_CASE_IMPORTANT(eCSSProperty_background_y_position, Color, mBackPositionY); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_clip, Color, mBackClip); + CSS_CASE_IMPORTANT(eCSSProperty__moz_background_origin, Color, mBackOrigin); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3272,7 +3284,9 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3282,6 +3296,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_attachment: theColor->mBackAttachment.Reset(); break; case eCSSProperty_background_x_position: theColor->mBackPositionX.Reset(); break; case eCSSProperty_background_y_position: theColor->mBackPositionY.Reset(); break; + case eCSSProperty__moz_background_clip: theColor->mBackClip.Reset(); break; + case eCSSProperty__moz_background_origin: theColor->mBackOrigin.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4100,7 +4116,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_repeat: case eCSSProperty_background_attachment: case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: { + case eCSSProperty_background_y_position: + case eCSSProperty__moz_background_clip: + case eCSSProperty__moz_background_origin: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4111,6 +4129,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_attachment: aValue = theColor->mBackAttachment; break; case eCSSProperty_background_x_position: aValue = theColor->mBackPositionX; break; case eCSSProperty_background_y_position: aValue = theColor->mBackPositionY; break; + case eCSSProperty__moz_background_clip: aValue = theColor->mBackClip; break; + case eCSSProperty__moz_background_origin: aValue = theColor->mBackOrigin; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/layout/style/nsCSSStruct.h b/layout/style/nsCSSStruct.h index 7f336020995..94f109babf4 100644 --- a/layout/style/nsCSSStruct.h +++ b/layout/style/nsCSSStruct.h @@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackAttachment; nsCSSValue mBackPositionX; nsCSSValue mBackPositionY; + nsCSSValue mBackClip; + nsCSSValue mBackOrigin; }; struct nsCSSShadow { diff --git a/layout/style/nsCSSStyleRule.cpp b/layout/style/nsCSSStyleRule.cpp index 0068e0962f8..d41b9570a60 100644 --- a/layout/style/nsCSSStyleRule.cpp +++ b/layout/style/nsCSSStyleRule.cpp @@ -2139,6 +2139,14 @@ MapColorForDeclaration(nsCSSDeclaration* aDecl, const nsStyleStructID& aID, nsCS aColor.mBackPositionX = ourColor->mBackPositionX; if (aColor.mBackPositionY.GetUnit() == eCSSUnit_Null && ourColor->mBackPositionY.GetUnit() != eCSSUnit_Null) aColor.mBackPositionY = ourColor->mBackPositionY; + + // background-clip: enum, inherit + if (aColor.mBackClip.GetUnit() == eCSSUnit_Null && ourColor->mBackClip.GetUnit() != eCSSUnit_Null) + aColor.mBackClip = ourColor->mBackClip; + + // background-origin: enum, inherit + if (aColor.mBackOrigin.GetUnit() == eCSSUnit_Null && ourColor->mBackOrigin.GetUnit() != eCSSUnit_Null) + aColor.mBackOrigin = ourColor->mBackOrigin; } return NS_OK; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index d6ec7a3af5f..fbd9849a9d0 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -682,6 +682,30 @@ nsComputedDOMStyle::GetBackgroundAttachment(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundClip(nsIFrame *aFrame, + nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleBackground *background = nsnull; + GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame); + + PRUint8 clip = NS_STYLE_BG_CLIP_BORDER; + if (background) { + clip = background->mBackgroundClip; + } + + const nsAFlatCString& backgroundClip = + nsCSSProps::SearchKeywordTable(clip, + nsCSSProps::kBackgroundClipKTable); + + val->SetIdent(backgroundClip); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundColor(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -739,6 +763,30 @@ nsComputedDOMStyle::GetBackgroundImage(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundOrigin(nsIFrame *aFrame, + nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleBackground *background = nsnull; + GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)background, aFrame); + + PRUint8 origin = NS_STYLE_BG_ORIGIN_PADDING; + if (background) { + origin = background->mBackgroundOrigin; + } + + const nsAFlatCString& backgroundOrigin = + nsCSSProps::SearchKeywordTable(origin, + nsCSSProps::kBackgroundOriginKTable); + + val->SetIdent(backgroundOrigin); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -3571,6 +3619,8 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) \* ******************************* */ COMPUTED_STYLE_MAP_ENTRY(appearance, Appearance), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_clip, BackgroundClip), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_origin, BackgroundOrigin), COMPUTED_STYLE_MAP_ENTRY(binding, Binding), COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors, BorderBottomColors), COMPUTED_STYLE_MAP_ENTRY(border_left_colors, BorderLeftColors), diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index a4757ecde20..1a4ac4b44de 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -174,6 +174,8 @@ private: nsresult GetBackgroundColor(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundImage(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundClip(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue); /* Padding properties */ nsresult GetPadding(nsIFrame *aFrame, nsIDOMCSSValue** aValue); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index bc6dc92f0df..e5b57765667 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -888,8 +888,10 @@ static const PropertyCheckData ColorCheckProperties[] = { static const PropertyCheckData BackgroundCheckProperties[] = { CHECKDATA_PROP(nsCSSColor, mBackAttachment, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackRepeat, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsCSSColor, mBackClip, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackColor, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackImage, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsCSSColor, mBackOrigin, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackPositionX, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsCSSColor, mBackPositionY, CHECKDATA_VALUE, PR_FALSE) }; @@ -3192,6 +3194,28 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, const nsCSSStruct bg->mBackgroundAttachment = parentBG->mBackgroundAttachment; } + // background-clip: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = colorData.mBackClip.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = parentBG->mBackgroundClip; + } + else if (eCSSUnit_Initial == colorData.mBackClip.GetUnit()) { + bg->mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; + } + + // background-origin: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = colorData.mBackOrigin.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = parentBG->mBackgroundOrigin; + } + else if (eCSSUnit_Initial == colorData.mBackOrigin.GetUnit()) { + bg->mBackgroundOrigin = NS_STYLE_BG_ORIGIN_PADDING; + } + // background-position: enum, length, percent (flags), inherit if (eCSSUnit_Percent == colorData.mBackPositionX.GetUnit()) { bg->mBackgroundXPosition = (nscoord)(100.0f * colorData.mBackPositionX.GetPercentValue()); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 9f04af9204e..28747838e73 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -977,6 +977,8 @@ nsStyleBackground::nsStyleBackground(nsIPresContext* aPresContext) mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE; aPresContext->GetDefaultBackgroundColor(&mBackgroundColor); mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL; + mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; + mBackgroundOrigin = NS_STYLE_BG_ORIGIN_PADDING; mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY; mBackgroundXPosition = mBackgroundYPosition = 0; } @@ -986,7 +988,8 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) mBackgroundAttachment = aSource.mBackgroundAttachment; mBackgroundFlags = aSource.mBackgroundFlags; mBackgroundRepeat = aSource.mBackgroundRepeat; - + mBackgroundClip = aSource.mBackgroundClip; + mBackgroundOrigin = aSource.mBackgroundOrigin; mBackgroundColor = aSource.mBackgroundColor; mBackgroundXPosition = aSource.mBackgroundXPosition; mBackgroundYPosition = aSource.mBackgroundYPosition; @@ -1007,6 +1010,8 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) (mBackgroundColor == aOther.mBackgroundColor) && (mBackgroundXPosition == aOther.mBackgroundXPosition) && (mBackgroundYPosition == aOther.mBackgroundYPosition) && + (mBackgroundClip == aOther.mBackgroundClip) && + (mBackgroundOrigin == aOther.mBackgroundOrigin) && (mBackgroundImage == aOther.mBackgroundImage)) return NS_STYLE_HINT_NONE; return NS_STYLE_HINT_VISUAL; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 9a5325d4617..34abbf57f14 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -156,10 +156,16 @@ struct nsStyleBackground : public nsStyleStruct { }; nsChangeHint CalcDifference(const nsStyleBackground& aOther) const; - - PRUint8 mBackgroundAttachment; // [reset] See nsStyleConsts.h - PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h - PRUint8 mBackgroundRepeat; // [reset] See nsStyleConsts.h + + // On Linux (others?), there is an extra byte being used up by + // inheritance so we only have 3 bytes to fit these 5 things into. + // Fortunately, the properties are enums which have few possible + // values. + PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundAttachment : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundClip : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundOrigin : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundRepeat : 4; // [reset] See nsStyleConsts.h nscolor mBackgroundColor; // [reset] nscoord mBackgroundXPosition; // [reset] diff --git a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index b6d52c3922b..65d5b568296 100644 --- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -797,12 +797,14 @@ nsSVGOuterSVGFrame::Paint(nsIPresContext* aPresContext, // // Paint our background and border // const nsStyleBorder* border = (const nsStyleBorder*) // mStyleContext->GetStyleData(eStyleStruct_Border); +// const nsStylePadding* padding = (const nsStylePadding*) +// mStyleContext->GetStyleData(eStyleStruct_Padding); // const nsStyleOutline* outline = (const nsStyleOutline*) // mStyleContext->GetStyleData(eStyleStruct_Outline); // nsRect rect(0, 0, mRect.width, mRect.height); // // nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, -// // aDirtyRect, rect, *border, 0, 0); +// // aDirtyRect, rect, *border, *padding, 0, 0); // nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, // aDirtyRect, rect, *border, mStyleContext, 0); // nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 43087b4ce48..405b16899e0 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -418,13 +418,15 @@ nsTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren) { if (aVisibleBackground) { nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(&aPresContext, aRenderingContext, this, - aDirtyRect, rect, aStyleBorder, 0, 0, PR_TRUE); + aDirtyRect, rect, aStyleBorder, aStylePadding, + 0, 0, PR_TRUE); // draw the border only when there is content or showing empty cells if (!GetContentEmpty() || NS_STYLE_TABLE_EMPTY_CELLS_SHOW == aCellTableStyle.mEmptyCells) { PRIntn skipSides = GetSkipSides(); @@ -455,11 +457,15 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { PRBool paintBackground = PR_FALSE; const nsStyleBorder* myBorder = nsnull; + const nsStylePadding* myPadding = nsnull; const nsStyleTableBorder* cellTableStyle = nsnull; const nsStyleVisibility* vis = (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility); if (vis->IsVisibleOrCollapsed()) { - myBorder = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); NS_ENSURE_TRUE(myBorder, NS_ERROR_NULL_POINTER); + myBorder = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + NS_ENSURE_TRUE(myBorder, NS_ERROR_NULL_POINTER); + myPadding = (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Border); + NS_ENSURE_TRUE(myPadding, NS_ERROR_NULL_POINTER); GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)cellTableStyle)); @@ -470,7 +476,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, } PaintUnderlay(*aPresContext, aRenderingContext, aDirtyRect, aFlags, *cellTableStyle, - *myBorder, paintBackground, paintChildren); + *myBorder, *myPadding, paintBackground, paintChildren); if (vis->IsVisibleOrCollapsed()) { const nsStyleBackground* myColor = @@ -1537,6 +1543,7 @@ nsBCTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren) { @@ -1561,7 +1568,8 @@ nsBCTableCellFrame::PaintUnderlay(nsIPresContext& aPresContext, nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(&aPresContext, aRenderingContext, this, - aDirtyRect, rect, myBorder, 0, 0, PR_TRUE); + aDirtyRect, rect, myBorder, aStylePadding, + 0, 0, PR_TRUE); // borders are painted by nsTableFrame } diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index e452dcb7599..79c6abdb838 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -302,6 +302,7 @@ protected: PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren); @@ -480,6 +481,7 @@ protected: PRUint32& aFlags, const nsStyleTableBorder& aCellTableStyle, const nsStyleBorder& aStyleBorder, + const nsStylePadding& aStylePadding, PRBool aVisibleBackground, PRBool& aPaintChildren); diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 29bbc301aa4..641ce693d31 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1463,10 +1463,13 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, if (vis && vis->IsVisibleOrCollapsed()) { const nsStyleBorder* border = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = + (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0, PR_TRUE); + aDirtyRect, rect, *border, *padding, + 0, 0, PR_TRUE); // paint the border here only for separate borders if (!IsBorderCollapse()) { diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp index f6e3e5cda2c..a8dfd89ff85 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -1606,12 +1606,15 @@ nsBoxFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* outline = (const nsStyleOutline*) mStyleContext->GetStyleData(eStyleStruct_Outline); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, diff --git a/layout/xul/base/src/nsDeckFrame.cpp b/layout/xul/base/src/nsDeckFrame.cpp index c0a0f7c279b..d503cc4c4ff 100644 --- a/layout/xul/base/src/nsDeckFrame.cpp +++ b/layout/xul/base/src/nsDeckFrame.cpp @@ -327,10 +327,13 @@ nsDeckFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* border = (const nsStyleBorder*) mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* padding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *border, 0, 0); + aDirtyRect, rect, *border, *padding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); } diff --git a/layout/xul/base/src/nsGroupBoxFrame.cpp b/layout/xul/base/src/nsGroupBoxFrame.cpp index 444df79481b..66ee4e619b3 100644 --- a/layout/xul/base/src/nsGroupBoxFrame.cpp +++ b/layout/xul/base/src/nsGroupBoxFrame.cpp @@ -129,6 +129,8 @@ nsGroupBoxFrame::Paint(nsIPresContext* aPresContext, PRIntn skipSides = GetSkipSides(); const nsStyleBorder* borderStyleData = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* paddingStyleData = + (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsMargin border; if (!borderStyleData->GetBorder(border)) { @@ -162,7 +164,7 @@ nsGroupBoxFrame::Paint(nsIPresContext* aPresContext, nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *borderStyleData, - 0, 0); + *paddingStyleData, 0, 0); if (groupBox) { diff --git a/layout/xul/base/src/nsSliderFrame.cpp b/layout/xul/base/src/nsSliderFrame.cpp index a5defe50c78..4661e8df22f 100644 --- a/layout/xul/base/src/nsSliderFrame.cpp +++ b/layout/xul/base/src/nsSliderFrame.cpp @@ -310,18 +310,19 @@ nsSliderFrame::Paint(nsIPresContext* aPresContext, if (crect.width < thumbRect.width || crect.height < thumbRect.height) { if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { - const nsStyleVisibility* vis = - (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility); + const nsStyleVisibility* vis = (const nsStyleVisibility*) + mStyleContext->GetStyleData(eStyleStruct_Visibility); if (vis->IsVisibleOrCollapsed()) { - const nsStyleBackground* myColor = (const nsStyleBackground*) - mStyleContext->GetStyleData(eStyleStruct_Background); const nsStyleBorder* myBorder = (const nsStyleBorder*) - mStyleContext->GetStyleData(eStyleStruct_Border); + mStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + mStyleContext->GetStyleData(eStyleStruct_Padding); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, 0, 0); + aDirtyRect, rect, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, mStyleContext, 0); + aDirtyRect, rect, *myBorder, mStyleContext, 0); } } return NS_OK; diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index 10d95ccc709..062a860eae7 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -3130,12 +3130,15 @@ nsTreeBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresCon aStyleContext->GetStyleData(eStyleStruct_Background); const nsStyleBorder* myBorder = (const nsStyleBorder*) aStyleContext->GetStyleData(eStyleStruct_Border); + const nsStylePadding* myPadding = (const nsStylePadding*) + aStyleContext->GetStyleData(eStyleStruct_Padding); const nsStyleOutline* myOutline = (const nsStyleOutline*) aStyleContext->GetStyleData(eStyleStruct_Outline); nsCSSRendering::PaintBackgroundWithSC(aPresContext, aRenderingContext, this, aDirtyRect, aRect, - *myColor, *myBorder, 0, 0); + *myColor, *myBorder, *myPadding, + 0, 0); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, aRect, *myBorder, mStyleContext, 0);