From 4e9b13ef00bcf646112ac2439cf2ed8df4c70166 Mon Sep 17 00:00:00 2001 From: "caillon%returnzero.com" Date: Fri, 17 Jan 2003 09:33:52 +0000 Subject: [PATCH] Bug 14777 - Give inline background image painting a rhyme and reason to how it works. Implement CSS3 proposal (-moz-)background-inline-policy. r+sr=roc+moz git-svn-id: svn://10.0.0.236/trunk@136499 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsRuleNode.cpp | 12 ++ .../html/style/src/nsCSSDeclaration.cpp | 21 ++- .../content/html/style/src/nsCSSDeclaration.h | 1 + .../content/html/style/src/nsCSSParser.cpp | 6 +- .../content/html/style/src/nsCSSStruct.cpp | 21 ++- mozilla/content/html/style/src/nsCSSStruct.h | 1 + .../content/html/style/src/nsCSSStyleRule.cpp | 4 + .../html/style/src/nsComputedDOMStyle.cpp | 25 +++ .../html/style/src/nsComputedDOMStyle.h | 1 + .../content/shared/public/nsCSSKeywordList.h | 2 + mozilla/content/shared/public/nsCSSPropList.h | 1 + mozilla/content/shared/public/nsCSSProps.h | 1 + mozilla/content/shared/public/nsStyleStruct.h | 27 ++- mozilla/content/shared/src/nsCSSProps.cpp | 10 + mozilla/content/shared/src/nsStyleStruct.cpp | 34 ++-- .../public/idl/css/nsIDOMCSS2Properties.idl | 3 + mozilla/layout/base/nsCSSRendering.cpp | 177 +++++++++++++++--- mozilla/layout/base/nsCSSRendering.h | 6 + mozilla/layout/base/nsPresShell.cpp | 5 + mozilla/layout/base/nsStyleConsts.h | 5 + mozilla/layout/base/public/nsStyleConsts.h | 5 + mozilla/layout/generic/nsObjectFrame.cpp | 8 +- .../layout/html/base/src/nsObjectFrame.cpp | 8 +- mozilla/layout/html/base/src/nsPresShell.cpp | 5 + .../layout/html/style/src/nsCSSRendering.cpp | 177 +++++++++++++++--- .../layout/html/style/src/nsCSSRendering.h | 6 + mozilla/layout/style/nsCSSDeclaration.cpp | 21 ++- mozilla/layout/style/nsCSSDeclaration.h | 1 + mozilla/layout/style/nsCSSKeywordList.h | 2 + mozilla/layout/style/nsCSSParser.cpp | 6 +- mozilla/layout/style/nsCSSPropList.h | 1 + mozilla/layout/style/nsCSSProps.cpp | 10 + mozilla/layout/style/nsCSSProps.h | 1 + mozilla/layout/style/nsCSSStruct.cpp | 21 ++- mozilla/layout/style/nsCSSStruct.h | 1 + mozilla/layout/style/nsCSSStyleRule.cpp | 4 + mozilla/layout/style/nsComputedDOMStyle.cpp | 25 +++ mozilla/layout/style/nsComputedDOMStyle.h | 1 + mozilla/layout/style/nsRuleNode.cpp | 12 ++ mozilla/layout/style/nsStyleStruct.cpp | 34 ++-- mozilla/layout/style/nsStyleStruct.h | 27 ++- 41 files changed, 607 insertions(+), 132 deletions(-) diff --git a/mozilla/content/base/src/nsRuleNode.cpp b/mozilla/content/base/src/nsRuleNode.cpp index 3fac10a7c1c..daa48117cd7 100644 --- a/mozilla/content/base/src/nsRuleNode.cpp +++ b/mozilla/content/base/src/nsRuleNode.cpp @@ -892,6 +892,7 @@ static const PropertyCheckData BackgroundCheckProperties[] = { CHECKDATA_PROP(nsRuleDataColor, mBackClip, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackColor, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackImage, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsRuleDataColor, mBackInlinePolicy, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackOrigin, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackPositionX, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackPositionY, CHECKDATA_VALUE, PR_FALSE) @@ -3254,6 +3255,17 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, bg->mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; } + // background-inline-policy: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = colorData.mBackInlinePolicy.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = parentBG->mBackgroundInlinePolicy; + } + else if (eCSSUnit_Initial == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS; + } + // background-origin: enum, inherit, initial if (eCSSUnit_Enumerated == colorData.mBackOrigin.GetUnit()) { bg->mBackgroundOrigin = colorData.mBackOrigin.GetIntValue(); diff --git a/mozilla/content/html/style/src/nsCSSDeclaration.cpp b/mozilla/content/html/style/src/nsCSSDeclaration.cpp index d41dcc66aa1..6140b031800 100644 --- a/mozilla/content/html/style/src/nsCSSDeclaration.cpp +++ b/mozilla/content/html/style/src/nsCSSDeclaration.cpp @@ -168,7 +168,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackPositionX(aCopy.mBackPositionX), mBackPositionY(aCopy.mBackPositionY), mBackClip(aCopy.mBackClip), - mBackOrigin(aCopy.mBackOrigin) + mBackOrigin(aCopy.mBackOrigin), + mBackInlinePolicy(aCopy.mBackInlinePolicy) + { MOZ_COUNT_CTOR(nsCSSColor); } @@ -199,6 +201,7 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); + mBackInlinePolicy.AppendToString(buffer, eCSSProperty__moz_background_inline_policy); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1476,7 +1479,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1488,6 +1492,7 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2319,7 +2324,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2333,6 +2339,7 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) 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_CASE_IMPORTANT(eCSSProperty__moz_background_inline_policy, Color, mBackInlinePolicy); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3285,7 +3292,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3297,6 +3305,7 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4117,7 +4126,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4130,6 +4140,7 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: aValue = theColor->mBackInlinePolicy; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/mozilla/content/html/style/src/nsCSSDeclaration.h b/mozilla/content/html/style/src/nsCSSDeclaration.h index 915aa6c7fd1..5b9b17a9620 100644 --- a/mozilla/content/html/style/src/nsCSSDeclaration.h +++ b/mozilla/content/html/style/src/nsCSSDeclaration.h @@ -177,6 +177,7 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackPositionY; nsCSSValue mBackClip; nsCSSValue mBackOrigin; + nsCSSValue mBackInlinePolicy; }; struct nsRuleDataColor : public nsCSSColor { diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index 9b556ee1295..2064316c122 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -3748,6 +3748,9 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode, nsCSSProps::kBackgroundColorKTable); case eCSSProperty_background_image: return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull); + case eCSSProperty__moz_background_inline_policy: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundInlinePolicyKTable); case eCSSProperty__moz_background_origin: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundOriginKTable); @@ -4247,9 +4250,10 @@ PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsCSSDeclaration* aDe } // Background properties not settable from the shorthand get reset to their initial value - const PRInt32 numResetProps = 2; + static const PRInt32 numResetProps = 3; static const nsCSSProperty kBackgroundResetIDs[numResetProps] = { eCSSProperty__moz_background_clip, + eCSSProperty__moz_background_inline_policy, eCSSProperty__moz_background_origin }; diff --git a/mozilla/content/html/style/src/nsCSSStruct.cpp b/mozilla/content/html/style/src/nsCSSStruct.cpp index d41dcc66aa1..6140b031800 100644 --- a/mozilla/content/html/style/src/nsCSSStruct.cpp +++ b/mozilla/content/html/style/src/nsCSSStruct.cpp @@ -168,7 +168,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackPositionX(aCopy.mBackPositionX), mBackPositionY(aCopy.mBackPositionY), mBackClip(aCopy.mBackClip), - mBackOrigin(aCopy.mBackOrigin) + mBackOrigin(aCopy.mBackOrigin), + mBackInlinePolicy(aCopy.mBackInlinePolicy) + { MOZ_COUNT_CTOR(nsCSSColor); } @@ -199,6 +201,7 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); + mBackInlinePolicy.AppendToString(buffer, eCSSProperty__moz_background_inline_policy); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1476,7 +1479,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1488,6 +1492,7 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2319,7 +2324,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2333,6 +2339,7 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) 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_CASE_IMPORTANT(eCSSProperty__moz_background_inline_policy, Color, mBackInlinePolicy); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3285,7 +3292,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3297,6 +3305,7 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4117,7 +4126,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4130,6 +4140,7 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: aValue = theColor->mBackInlinePolicy; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/mozilla/content/html/style/src/nsCSSStruct.h b/mozilla/content/html/style/src/nsCSSStruct.h index 915aa6c7fd1..5b9b17a9620 100644 --- a/mozilla/content/html/style/src/nsCSSStruct.h +++ b/mozilla/content/html/style/src/nsCSSStruct.h @@ -177,6 +177,7 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackPositionY; nsCSSValue mBackClip; nsCSSValue mBackOrigin; + nsCSSValue mBackInlinePolicy; }; struct nsRuleDataColor : public nsCSSColor { diff --git a/mozilla/content/html/style/src/nsCSSStyleRule.cpp b/mozilla/content/html/style/src/nsCSSStyleRule.cpp index ad83c0e1430..21dfe693487 100644 --- a/mozilla/content/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleRule.cpp @@ -2142,6 +2142,10 @@ MapColorForDeclaration(nsCSSDeclaration* aDecl, const nsStyleStructID& aID, nsRu if (aColor.mBackClip.GetUnit() == eCSSUnit_Null && ourColor->mBackClip.GetUnit() != eCSSUnit_Null) aColor.mBackClip = ourColor->mBackClip; + // background-inline-policy: enum, inherit + if (aColor.mBackInlinePolicy.GetUnit() == eCSSUnit_Null && ourColor->mBackInlinePolicy.GetUnit() != eCSSUnit_Null) + aColor.mBackInlinePolicy = ourColor->mBackInlinePolicy; + // background-origin: enum, inherit if (aColor.mBackOrigin.GetUnit() == eCSSUnit_Null && ourColor->mBackOrigin.GetUnit() != eCSSUnit_Null) aColor.mBackOrigin = ourColor->mBackOrigin; diff --git a/mozilla/content/html/style/src/nsComputedDOMStyle.cpp b/mozilla/content/html/style/src/nsComputedDOMStyle.cpp index 6356a06061d..da99794db63 100644 --- a/mozilla/content/html/style/src/nsComputedDOMStyle.cpp +++ b/mozilla/content/html/style/src/nsComputedDOMStyle.cpp @@ -762,6 +762,30 @@ nsComputedDOMStyle::GetBackgroundImage(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundInlinePolicy(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 policy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS; + if (background) { + policy = background->mBackgroundInlinePolicy; + } + + const nsAFlatCString& backgroundPolicy = + nsCSSProps::SearchKeywordTable(policy, + nsCSSProps::kBackgroundInlinePolicyKTable); + + val->SetIdent(backgroundPolicy); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -3599,6 +3623,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) COMPUTED_STYLE_MAP_ENTRY(appearance, Appearance), COMPUTED_STYLE_MAP_ENTRY(_moz_background_clip, BackgroundClip), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_inline_policy, BackgroundInlinePolicy), COMPUTED_STYLE_MAP_ENTRY(_moz_background_origin, BackgroundOrigin), COMPUTED_STYLE_MAP_ENTRY(binding, Binding), COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors, BorderBottomColors), diff --git a/mozilla/content/html/style/src/nsComputedDOMStyle.h b/mozilla/content/html/style/src/nsComputedDOMStyle.h index 22f982d1fab..cdcd52b9dd3 100644 --- a/mozilla/content/html/style/src/nsComputedDOMStyle.h +++ b/mozilla/content/html/style/src/nsComputedDOMStyle.h @@ -177,6 +177,7 @@ private: nsresult GetBackgroundImage(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundClip(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundInlinePolicy(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue); /* Padding properties */ diff --git a/mozilla/content/shared/public/nsCSSKeywordList.h b/mozilla/content/shared/public/nsCSSKeywordList.h index 3f762a2d583..d756a96c409 100644 --- a/mozilla/content/shared/public/nsCSSKeywordList.h +++ b/mozilla/content/shared/public/nsCSSKeywordList.h @@ -185,6 +185,7 @@ CSS_KEY(border, border) CSS_KEY(border-box, border_box) CSS_KEY(both, both) CSS_KEY(bottom, bottom) +CSS_KEY(bounding-box, bounding_box) CSS_KEY(button, button) CSS_KEY(buttonface, buttonface) CSS_KEY(buttonhighlight, buttonhighlight) @@ -222,6 +223,7 @@ CSS_KEY(disc, disc) CSS_KEY(dotted, dotted) CSS_KEY(double, double) CSS_KEY(e-resize, e_resize) +CSS_KEY(each-box, each_box) CSS_KEY(element, element) CSS_KEY(elements, elements) CSS_KEY(em, em) diff --git a/mozilla/content/shared/public/nsCSSPropList.h b/mozilla/content/shared/public/nsCSSPropList.h index 7c13710474a..e4b7d71d127 100644 --- a/mozilla/content/shared/public/nsCSSPropList.h +++ b/mozilla/content/shared/public/nsCSSPropList.h @@ -112,6 +112,7 @@ CSS_PROP(background-attachment, background_attachment, BackgroundAttachment, NS_ 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-inline-policy, _moz_background_inline_policy, MozBackgroundInlinePolicy, 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) diff --git a/mozilla/content/shared/public/nsCSSProps.h b/mozilla/content/shared/public/nsCSSProps.h index bd77f3ae95b..1508a903d42 100644 --- a/mozilla/content/shared/public/nsCSSProps.h +++ b/mozilla/content/shared/public/nsCSSProps.h @@ -89,6 +89,7 @@ public: static const PRInt32 kBackgroundAttachmentKTable[]; static const PRInt32 kBackgroundClipKTable[]; static const PRInt32 kBackgroundColorKTable[]; + static const PRInt32 kBackgroundInlinePolicyKTable[]; static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; static const PRInt32 kBorderCollapseKTable[]; diff --git a/mozilla/content/shared/public/nsStyleStruct.h b/mozilla/content/shared/public/nsStyleStruct.h index 493c96f914b..0fbd1df1ddf 100644 --- a/mozilla/content/shared/public/nsStyleStruct.h +++ b/mozilla/content/shared/public/nsStyleStruct.h @@ -158,23 +158,32 @@ struct nsStyleBackground : public nsStyleStruct { nsChangeHint CalcDifference(const nsStyleBackground& aOther) const; // 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. + // inheritance so we only have 3 bytes to fit these 6 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 + PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundAttachment : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundClip : 3; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundInlinePolicy : 2; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundOrigin : 3; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundRepeat : 4; // [reset] See nsStyleConsts.h nscolor mBackgroundColor; // [reset] nscoord mBackgroundXPosition; // [reset] nscoord mBackgroundYPosition; // [reset] nsString mBackgroundImage; // [reset] absolute url string - PRBool BackgroundIsTransparent() const {return (mBackgroundFlags & - (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE)) == - (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE);} + PRBool IsTransparent() const + { + return (mBackgroundFlags & + (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE)) == + (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE); + } + + PRBool IsPositioned() const + { + return mBackgroundXPosition != 0 || mBackgroundYPosition != 0; + } }; #define BORDER_COLOR_DEFINED 0x80 diff --git a/mozilla/content/shared/src/nsCSSProps.cpp b/mozilla/content/shared/src/nsCSSProps.cpp index a65987c061d..f316aa0720e 100644 --- a/mozilla/content/shared/src/nsCSSProps.cpp +++ b/mozilla/content/shared/src/nsCSSProps.cpp @@ -234,6 +234,13 @@ const PRInt32 nsCSSProps::kBackgroundClipKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundInlinePolicyKTable[] = { + eCSSKeyword_each_box, NS_STYLE_BG_INLINE_POLICY_EACH_BOX, + eCSSKeyword_continuous, NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, + eCSSKeyword_bounding_box, NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX, + -1,-1 +}; + const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = { eCSSKeyword_border, NS_STYLE_BG_ORIGIN_BORDER, eCSSKeyword_padding, NS_STYLE_BG_ORIGIN_PADDING, @@ -942,6 +949,9 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty__moz_background_clip: return SearchKeywordTable(aValue, kBackgroundClipKTable); + case eCSSProperty__moz_background_inline_policy: + return SearchKeywordTable(aValue, kBackgroundInlinePolicyKTable); + case eCSSProperty__moz_background_origin: return SearchKeywordTable(aValue, kBackgroundOriginKTable); diff --git a/mozilla/content/shared/src/nsStyleStruct.cpp b/mozilla/content/shared/src/nsStyleStruct.cpp index 6bbf26a5e9d..8f9563f8dbd 100644 --- a/mozilla/content/shared/src/nsStyleStruct.cpp +++ b/mozilla/content/shared/src/nsStyleStruct.cpp @@ -971,27 +971,30 @@ nsChangeHint nsStyleColor::CalcDifference(const nsStyleColor& aOther) const // nsStyleBackground::nsStyleBackground(nsIPresContext* aPresContext) + : mBackgroundFlags(NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE), + mBackgroundAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL), + mBackgroundClip(NS_STYLE_BG_CLIP_BORDER), + mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS), + mBackgroundOrigin(NS_STYLE_BG_ORIGIN_PADDING), + mBackgroundRepeat(NS_STYLE_BG_REPEAT_XY), + mBackgroundXPosition(0), + mBackgroundYPosition(0) { - 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; } nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) + : mBackgroundFlags(aSource.mBackgroundFlags), + mBackgroundAttachment(aSource.mBackgroundAttachment), + mBackgroundClip(aSource.mBackgroundClip), + mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy), + mBackgroundOrigin(aSource.mBackgroundOrigin), + mBackgroundRepeat(aSource.mBackgroundRepeat), + mBackgroundColor(aSource.mBackgroundColor), + mBackgroundXPosition(aSource.mBackgroundXPosition), + mBackgroundYPosition(aSource.mBackgroundYPosition), + mBackgroundImage(aSource.mBackgroundImage) { - mBackgroundAttachment = aSource.mBackgroundAttachment; - mBackgroundFlags = aSource.mBackgroundFlags; - mBackgroundRepeat = aSource.mBackgroundRepeat; - mBackgroundClip = aSource.mBackgroundClip; - mBackgroundOrigin = aSource.mBackgroundOrigin; - mBackgroundColor = aSource.mBackgroundColor; - mBackgroundXPosition = aSource.mBackgroundXPosition; - mBackgroundYPosition = aSource.mBackgroundYPosition; - mBackgroundImage = aSource.mBackgroundImage; } nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const @@ -1009,6 +1012,7 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) (mBackgroundXPosition == aOther.mBackgroundXPosition) && (mBackgroundYPosition == aOther.mBackgroundYPosition) && (mBackgroundClip == aOther.mBackgroundClip) && + (mBackgroundInlinePolicy == aOther.mBackgroundInlinePolicy) && (mBackgroundOrigin == aOther.mBackgroundOrigin) && (mBackgroundImage == aOther.mBackgroundImage)) return NS_STYLE_HINT_NONE; diff --git a/mozilla/dom/public/idl/css/nsIDOMCSS2Properties.idl b/mozilla/dom/public/idl/css/nsIDOMCSS2Properties.idl index 886e3c26c04..8d46fee5a07 100644 --- a/mozilla/dom/public/idl/css/nsIDOMCSS2Properties.idl +++ b/mozilla/dom/public/idl/css/nsIDOMCSS2Properties.idl @@ -420,6 +420,9 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties attribute DOMString MozBackgroundClip; // raises(DOMException) on setting + attribute DOMString MozBackgroundInlinePolicy; + // raises(DOMException) on setting + attribute DOMString MozBackgroundOrigin; // raises(DOMException) on setting diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 627a43308c0..a766973cadd 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -84,6 +84,120 @@ enum ePathTypes{ eCalcRev }; +// To avoid storing this data on nsInlineFrame (bloat) and to avoid +// recalculating this for each frame in a continuation (perf), hold +// a cache of various coordinate information that we need in order +// to paint inline backgrounds. +struct InlineBackgroundData +{ + InlineBackgroundData() + : mFrame(nsnull) + { + } + + ~InlineBackgroundData() + { + } + + void Reset() + { + mBoundingBox.SetRect(0,0,0,0); + mContinuationPoint = mUnbrokenWidth = 0; + mFrame = nsnull; + } + + nsRect GetContinuousRect(nsIFrame* aFrame) + { + SetFrame(aFrame); + + nsSize size; + mFrame->GetSize(size); + + // Assume background-origin: border and return a rect with offsets + // relative to (0,0). If we have a different background-origin, + // then our rect should be deflated appropriately by our caller. + return nsRect(-mContinuationPoint, 0, mUnbrokenWidth, size.height); + } + + nsRect GetBoundingRect(nsIFrame* aFrame) + { + SetFrame(aFrame); + + nsPoint point; + mFrame->GetOrigin(point); + + // Move the offsets relative to (0,0) which puts the bounding box into + // our coordinate system rather than our parent's. We do this by + // moving it the back distance from us to the bounding box. + // This also assumes background-origin: border, so our caller will + // need to deflate us if needed. + nsRect boundingBox(mBoundingBox); + boundingBox.MoveBy(-point.x, -point.y); + + return boundingBox; + } + +protected: + nsIFrame* mFrame; + nscoord mContinuationPoint; + nscoord mUnbrokenWidth; + nsRect mBoundingBox; + + void SetFrame(nsIFrame* aFrame) + { + NS_PRECONDITION(aFrame, "Need a frame"); + + nsIFrame *prevInFlow = nsnull; + aFrame->GetPrevInFlow(&prevInFlow); + + if (!prevInFlow || mFrame != prevInFlow) { + // Ok, we've got the wrong frame. We have to start from scratch. + Reset(); + Init(aFrame); + return; + } + + // Get our last frame's size and add its width to our continuation + // point before we cache the new frame. + nsSize size; + mFrame->GetSize(size); + mContinuationPoint += size.width; + + mFrame = aFrame; + } + + void Init(nsIFrame* aFrame) + { + nsIFrame* inlineFrame; + // Start with the previous flow frame as our continuation point + // is the total of the widths of the previous frames. + aFrame->GetPrevInFlow(&inlineFrame); + + nsRect rect; + while (inlineFrame) { + inlineFrame->GetRect(rect); + mContinuationPoint += rect.width; + mUnbrokenWidth += rect.width; + mBoundingBox.UnionRect(mBoundingBox, rect); + inlineFrame->GetPrevInFlow(&inlineFrame); + } + + // Next add this frame and subsequent frames to the bounding box and + // unbroken width. + inlineFrame = aFrame; + while (inlineFrame) { + inlineFrame->GetRect(rect); + mUnbrokenWidth += rect.width; + mBoundingBox.UnionRect(mBoundingBox, rect); + inlineFrame->GetNextInFlow(&inlineFrame); + } + + mFrame = aFrame; + } +}; + +static InlineBackgroundData gInlineBGData; + static void GetPath(nsFloatPoint aPoints[],nsPoint aPolyPath[],PRInt32 *aCurIndex,ePathTypes aPathType,PRInt32 &aC1Index,float aFrac=0); static nsresult GetFrameForBackgroundUpdate(nsIPresContext *aPresContext,nsIFrame *aFrame, nsIFrame **aBGFrame); @@ -2500,8 +2614,8 @@ FindCanvasBackground(nsIPresContext* aPresContext, while(firstChild){ for (nsIFrame* kidFrame = firstChild; nsnull != kidFrame; ) { kidFrame->GetStyleContext(getter_AddRefs(parentContext)); - result = (nsStyleBackground*)parentContext->GetStyleData(eStyleStruct_Background); - if (!result->BackgroundIsTransparent()){ + ::GetStyleData(parentContext, &result); + if (!result->IsTransparent()) { GetStyleData(kidFrame, aBackground); return PR_TRUE; } else { @@ -2514,7 +2628,7 @@ FindCanvasBackground(nsIPresContext* aPresContext, } // Check if we need to do propagation from BODY rather than HTML. - if (result->BackgroundIsTransparent()) { + if (result->IsTransparent()) { nsCOMPtr content; aForFrame->GetContent(getter_AddRefs(content)); if (content) { @@ -2600,7 +2714,7 @@ FindElementBackground(nsIPresContext* aPresContext, const nsStyleBackground *htmlBG; ::GetStyleData(parentFrame, &htmlBG); - return !htmlBG->BackgroundIsTransparent(); + return !htmlBG->IsTransparent(); } PRBool @@ -2616,6 +2730,12 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext, : FindElementBackground(aPresContext, aForFrame, aBackground); } +void +nsCSSRendering::DidPaint() +{ + gInlineBGData.Reset(); +} + void nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -2808,9 +2928,32 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, req = nsnull; + nsRect bgOriginArea; + + nsCOMPtr frameType; + aForFrame->GetFrameType(getter_AddRefs(frameType)); + if (frameType == nsLayoutAtoms::inlineFrame) { + switch (aColor.mBackgroundInlinePolicy) { + case NS_STYLE_BG_INLINE_POLICY_EACH_BOX: + bgOriginArea = aBorderArea; + break; + case NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX: + bgOriginArea = gInlineBGData.GetBoundingRect(aForFrame); + break; + default: + NS_ERROR("Unknown background-inline-policy value! " + "Please, teach me what to do."); + case NS_STYLE_BG_INLINE_POLICY_CONTINUOUS: + bgOriginArea = gInlineBGData.GetContinuousRect(aForFrame); + break; + } + } + else { + bgOriginArea = aBorderArea; + } + // 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)) { @@ -2836,7 +2979,6 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, 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_X: @@ -2846,12 +2988,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, case NS_STYLE_BG_REPEAT_Y: xDistance = tileWidth; yDistance = dirtyRect.height; - needBackgroundOnContinuation = PR_TRUE; break; case NS_STYLE_BG_REPEAT_XY: xDistance = dirtyRect.width; yDistance = dirtyRect.height; - needBackgroundOnContinuation = PR_TRUE; // We need to render the background color if the image is transparent //needBackgroundColor = image->GetHasAlphaMask(); break; @@ -2874,25 +3014,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, 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 + // from the background-origin area. nsPoint anchor; if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { @@ -2982,9 +3107,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, view->GetParent(view); } } else { - nsCOMPtr frameType; - aForFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() == nsLayoutAtoms::canvasFrame) { + if (frameType == 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; diff --git a/mozilla/layout/base/nsCSSRendering.h b/mozilla/layout/base/nsCSSRendering.h index ef9be35158a..ced171f90fa 100644 --- a/mozilla/layout/base/nsCSSRendering.h +++ b/mozilla/layout/base/nsCSSRendering.h @@ -160,6 +160,12 @@ public: nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); + /** + * Called by the presShell when painting is finished, so we can clear our + * inline background data cache. + */ + static void DidPaint(); + static void DrawDashedSides(PRIntn startSide, nsIRenderingContext& aContext, diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 3e88f59826e..4d87d5b621d 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -109,6 +109,7 @@ #include "nsIDOMRange.h" #include "nsLayoutErrors.h" #include "nsLayoutUtils.h" +#include "nsCSSRendering.h" #ifdef MOZ_PERF_METRICS #include "nsITimeRecorder.h" #endif @@ -7319,6 +7320,8 @@ PresShellViewEventListener::DidRefreshRegion(nsIViewManager *aViewManager, nsIRegion *aRegion, PRUint32 aUpdateFlags) { + nsCSSRendering::DidPaint(); + return RestoreCaretVisibility(); } @@ -7339,6 +7342,8 @@ PresShellViewEventListener::DidRefreshRect(nsIViewManager *aViewManager, const nsRect *aRect, PRUint32 aUpdateFlags) { + nsCSSRendering::DidPaint(); + return RestoreCaretVisibility(); } diff --git a/mozilla/layout/base/nsStyleConsts.h b/mozilla/layout/base/nsStyleConsts.h index b4a258a315b..af52e199fab 100644 --- a/mozilla/layout/base/nsStyleConsts.h +++ b/mozilla/layout/base/nsStyleConsts.h @@ -213,6 +213,11 @@ #define NS_STYLE_BG_CLIP_BORDER 0 #define NS_STYLE_BG_CLIP_PADDING 1 +// See nsStyleBackground +#define NS_STYLE_BG_INLINE_POLICY_EACH_BOX 0 +#define NS_STYLE_BG_INLINE_POLICY_CONTINUOUS 1 +#define NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX 2 + // See nsStyleBackground #define NS_STYLE_BG_ORIGIN_BORDER 0 #define NS_STYLE_BG_ORIGIN_PADDING 1 diff --git a/mozilla/layout/base/public/nsStyleConsts.h b/mozilla/layout/base/public/nsStyleConsts.h index b4a258a315b..af52e199fab 100644 --- a/mozilla/layout/base/public/nsStyleConsts.h +++ b/mozilla/layout/base/public/nsStyleConsts.h @@ -213,6 +213,11 @@ #define NS_STYLE_BG_CLIP_BORDER 0 #define NS_STYLE_BG_CLIP_PADDING 1 +// See nsStyleBackground +#define NS_STYLE_BG_INLINE_POLICY_EACH_BOX 0 +#define NS_STYLE_BG_INLINE_POLICY_CONTINUOUS 1 +#define NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX 2 + // See nsStyleBackground #define NS_STYLE_BG_ORIGIN_BORDER 0 #define NS_STYLE_BG_ORIGIN_PADDING 1 diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index 9ed8039bdba..a5b508ecba5 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -808,13 +808,13 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext, // Sometimes, a frame doesn't have a background color or is transparent. In this // case, walk up the frame tree until we do find a frame with a background color for (nsIFrame* frame = this; frame; frame->GetParent(&frame)) { - const nsStyleBackground* color; - frame->GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)color); - if (!color->BackgroundIsTransparent()) { // make sure we got an actual color + const nsStyleBackground* background; + ::GetStyleData(frame, &background); + if (!background->IsTransparent()) { // make sure we got an actual color nsCOMPtr win; view->GetWidget(*getter_AddRefs(win)); if (win) - win->SetBackgroundColor(color->mBackgroundColor); + win->SetBackgroundColor(background->mBackgroundColor); break; } } diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index 9ed8039bdba..a5b508ecba5 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -808,13 +808,13 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext, // Sometimes, a frame doesn't have a background color or is transparent. In this // case, walk up the frame tree until we do find a frame with a background color for (nsIFrame* frame = this; frame; frame->GetParent(&frame)) { - const nsStyleBackground* color; - frame->GetStyleData(eStyleStruct_Background, (const nsStyleStruct*&)color); - if (!color->BackgroundIsTransparent()) { // make sure we got an actual color + const nsStyleBackground* background; + ::GetStyleData(frame, &background); + if (!background->IsTransparent()) { // make sure we got an actual color nsCOMPtr win; view->GetWidget(*getter_AddRefs(win)); if (win) - win->SetBackgroundColor(color->mBackgroundColor); + win->SetBackgroundColor(background->mBackgroundColor); break; } } diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 3e88f59826e..4d87d5b621d 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -109,6 +109,7 @@ #include "nsIDOMRange.h" #include "nsLayoutErrors.h" #include "nsLayoutUtils.h" +#include "nsCSSRendering.h" #ifdef MOZ_PERF_METRICS #include "nsITimeRecorder.h" #endif @@ -7319,6 +7320,8 @@ PresShellViewEventListener::DidRefreshRegion(nsIViewManager *aViewManager, nsIRegion *aRegion, PRUint32 aUpdateFlags) { + nsCSSRendering::DidPaint(); + return RestoreCaretVisibility(); } @@ -7339,6 +7342,8 @@ PresShellViewEventListener::DidRefreshRect(nsIViewManager *aViewManager, const nsRect *aRect, PRUint32 aUpdateFlags) { + nsCSSRendering::DidPaint(); + return RestoreCaretVisibility(); } diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index 627a43308c0..a766973cadd 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -84,6 +84,120 @@ enum ePathTypes{ eCalcRev }; +// To avoid storing this data on nsInlineFrame (bloat) and to avoid +// recalculating this for each frame in a continuation (perf), hold +// a cache of various coordinate information that we need in order +// to paint inline backgrounds. +struct InlineBackgroundData +{ + InlineBackgroundData() + : mFrame(nsnull) + { + } + + ~InlineBackgroundData() + { + } + + void Reset() + { + mBoundingBox.SetRect(0,0,0,0); + mContinuationPoint = mUnbrokenWidth = 0; + mFrame = nsnull; + } + + nsRect GetContinuousRect(nsIFrame* aFrame) + { + SetFrame(aFrame); + + nsSize size; + mFrame->GetSize(size); + + // Assume background-origin: border and return a rect with offsets + // relative to (0,0). If we have a different background-origin, + // then our rect should be deflated appropriately by our caller. + return nsRect(-mContinuationPoint, 0, mUnbrokenWidth, size.height); + } + + nsRect GetBoundingRect(nsIFrame* aFrame) + { + SetFrame(aFrame); + + nsPoint point; + mFrame->GetOrigin(point); + + // Move the offsets relative to (0,0) which puts the bounding box into + // our coordinate system rather than our parent's. We do this by + // moving it the back distance from us to the bounding box. + // This also assumes background-origin: border, so our caller will + // need to deflate us if needed. + nsRect boundingBox(mBoundingBox); + boundingBox.MoveBy(-point.x, -point.y); + + return boundingBox; + } + +protected: + nsIFrame* mFrame; + nscoord mContinuationPoint; + nscoord mUnbrokenWidth; + nsRect mBoundingBox; + + void SetFrame(nsIFrame* aFrame) + { + NS_PRECONDITION(aFrame, "Need a frame"); + + nsIFrame *prevInFlow = nsnull; + aFrame->GetPrevInFlow(&prevInFlow); + + if (!prevInFlow || mFrame != prevInFlow) { + // Ok, we've got the wrong frame. We have to start from scratch. + Reset(); + Init(aFrame); + return; + } + + // Get our last frame's size and add its width to our continuation + // point before we cache the new frame. + nsSize size; + mFrame->GetSize(size); + mContinuationPoint += size.width; + + mFrame = aFrame; + } + + void Init(nsIFrame* aFrame) + { + nsIFrame* inlineFrame; + // Start with the previous flow frame as our continuation point + // is the total of the widths of the previous frames. + aFrame->GetPrevInFlow(&inlineFrame); + + nsRect rect; + while (inlineFrame) { + inlineFrame->GetRect(rect); + mContinuationPoint += rect.width; + mUnbrokenWidth += rect.width; + mBoundingBox.UnionRect(mBoundingBox, rect); + inlineFrame->GetPrevInFlow(&inlineFrame); + } + + // Next add this frame and subsequent frames to the bounding box and + // unbroken width. + inlineFrame = aFrame; + while (inlineFrame) { + inlineFrame->GetRect(rect); + mUnbrokenWidth += rect.width; + mBoundingBox.UnionRect(mBoundingBox, rect); + inlineFrame->GetNextInFlow(&inlineFrame); + } + + mFrame = aFrame; + } +}; + +static InlineBackgroundData gInlineBGData; + static void GetPath(nsFloatPoint aPoints[],nsPoint aPolyPath[],PRInt32 *aCurIndex,ePathTypes aPathType,PRInt32 &aC1Index,float aFrac=0); static nsresult GetFrameForBackgroundUpdate(nsIPresContext *aPresContext,nsIFrame *aFrame, nsIFrame **aBGFrame); @@ -2500,8 +2614,8 @@ FindCanvasBackground(nsIPresContext* aPresContext, while(firstChild){ for (nsIFrame* kidFrame = firstChild; nsnull != kidFrame; ) { kidFrame->GetStyleContext(getter_AddRefs(parentContext)); - result = (nsStyleBackground*)parentContext->GetStyleData(eStyleStruct_Background); - if (!result->BackgroundIsTransparent()){ + ::GetStyleData(parentContext, &result); + if (!result->IsTransparent()) { GetStyleData(kidFrame, aBackground); return PR_TRUE; } else { @@ -2514,7 +2628,7 @@ FindCanvasBackground(nsIPresContext* aPresContext, } // Check if we need to do propagation from BODY rather than HTML. - if (result->BackgroundIsTransparent()) { + if (result->IsTransparent()) { nsCOMPtr content; aForFrame->GetContent(getter_AddRefs(content)); if (content) { @@ -2600,7 +2714,7 @@ FindElementBackground(nsIPresContext* aPresContext, const nsStyleBackground *htmlBG; ::GetStyleData(parentFrame, &htmlBG); - return !htmlBG->BackgroundIsTransparent(); + return !htmlBG->IsTransparent(); } PRBool @@ -2616,6 +2730,12 @@ nsCSSRendering::FindBackground(nsIPresContext* aPresContext, : FindElementBackground(aPresContext, aForFrame, aBackground); } +void +nsCSSRendering::DidPaint() +{ + gInlineBGData.Reset(); +} + void nsCSSRendering::PaintBackground(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -2808,9 +2928,32 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, req = nsnull; + nsRect bgOriginArea; + + nsCOMPtr frameType; + aForFrame->GetFrameType(getter_AddRefs(frameType)); + if (frameType == nsLayoutAtoms::inlineFrame) { + switch (aColor.mBackgroundInlinePolicy) { + case NS_STYLE_BG_INLINE_POLICY_EACH_BOX: + bgOriginArea = aBorderArea; + break; + case NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX: + bgOriginArea = gInlineBGData.GetBoundingRect(aForFrame); + break; + default: + NS_ERROR("Unknown background-inline-policy value! " + "Please, teach me what to do."); + case NS_STYLE_BG_INLINE_POLICY_CONTINUOUS: + bgOriginArea = gInlineBGData.GetContinuousRect(aForFrame); + break; + } + } + else { + bgOriginArea = aBorderArea; + } + // 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)) { @@ -2836,7 +2979,6 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, 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_X: @@ -2846,12 +2988,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, case NS_STYLE_BG_REPEAT_Y: xDistance = tileWidth; yDistance = dirtyRect.height; - needBackgroundOnContinuation = PR_TRUE; break; case NS_STYLE_BG_REPEAT_XY: xDistance = dirtyRect.width; yDistance = dirtyRect.height; - needBackgroundOnContinuation = PR_TRUE; // We need to render the background color if the image is transparent //needBackgroundColor = image->GetHasAlphaMask(); break; @@ -2874,25 +3014,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, 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 + // from the background-origin area. nsPoint anchor; if (NS_STYLE_BG_ATTACHMENT_FIXED == aColor.mBackgroundAttachment) { @@ -2982,9 +3107,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsIPresContext* aPresContext, view->GetParent(view); } } else { - nsCOMPtr frameType; - aForFrame->GetFrameType(getter_AddRefs(frameType)); - if (frameType.get() == nsLayoutAtoms::canvasFrame) { + if (frameType == 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; diff --git a/mozilla/layout/html/style/src/nsCSSRendering.h b/mozilla/layout/html/style/src/nsCSSRendering.h index ef9be35158a..ced171f90fa 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.h +++ b/mozilla/layout/html/style/src/nsCSSRendering.h @@ -160,6 +160,12 @@ public: nscoord aDX, nscoord aDY, PRBool aUsePrintSettings=PR_FALSE); + /** + * Called by the presShell when painting is finished, so we can clear our + * inline background data cache. + */ + static void DidPaint(); + static void DrawDashedSides(PRIntn startSide, nsIRenderingContext& aContext, diff --git a/mozilla/layout/style/nsCSSDeclaration.cpp b/mozilla/layout/style/nsCSSDeclaration.cpp index d41dcc66aa1..6140b031800 100644 --- a/mozilla/layout/style/nsCSSDeclaration.cpp +++ b/mozilla/layout/style/nsCSSDeclaration.cpp @@ -168,7 +168,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackPositionX(aCopy.mBackPositionX), mBackPositionY(aCopy.mBackPositionY), mBackClip(aCopy.mBackClip), - mBackOrigin(aCopy.mBackOrigin) + mBackOrigin(aCopy.mBackOrigin), + mBackInlinePolicy(aCopy.mBackInlinePolicy) + { MOZ_COUNT_CTOR(nsCSSColor); } @@ -199,6 +201,7 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); + mBackInlinePolicy.AppendToString(buffer, eCSSProperty__moz_background_inline_policy); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1476,7 +1479,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1488,6 +1492,7 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2319,7 +2324,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2333,6 +2339,7 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) 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_CASE_IMPORTANT(eCSSProperty__moz_background_inline_policy, Color, mBackInlinePolicy); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3285,7 +3292,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3297,6 +3305,7 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4117,7 +4126,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4130,6 +4140,7 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: aValue = theColor->mBackInlinePolicy; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/mozilla/layout/style/nsCSSDeclaration.h b/mozilla/layout/style/nsCSSDeclaration.h index 915aa6c7fd1..5b9b17a9620 100644 --- a/mozilla/layout/style/nsCSSDeclaration.h +++ b/mozilla/layout/style/nsCSSDeclaration.h @@ -177,6 +177,7 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackPositionY; nsCSSValue mBackClip; nsCSSValue mBackOrigin; + nsCSSValue mBackInlinePolicy; }; struct nsRuleDataColor : public nsCSSColor { diff --git a/mozilla/layout/style/nsCSSKeywordList.h b/mozilla/layout/style/nsCSSKeywordList.h index 3f762a2d583..d756a96c409 100644 --- a/mozilla/layout/style/nsCSSKeywordList.h +++ b/mozilla/layout/style/nsCSSKeywordList.h @@ -185,6 +185,7 @@ CSS_KEY(border, border) CSS_KEY(border-box, border_box) CSS_KEY(both, both) CSS_KEY(bottom, bottom) +CSS_KEY(bounding-box, bounding_box) CSS_KEY(button, button) CSS_KEY(buttonface, buttonface) CSS_KEY(buttonhighlight, buttonhighlight) @@ -222,6 +223,7 @@ CSS_KEY(disc, disc) CSS_KEY(dotted, dotted) CSS_KEY(double, double) CSS_KEY(e-resize, e_resize) +CSS_KEY(each-box, each_box) CSS_KEY(element, element) CSS_KEY(elements, elements) CSS_KEY(em, em) diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index 9b556ee1295..2064316c122 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -3748,6 +3748,9 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode, nsCSSProps::kBackgroundColorKTable); case eCSSProperty_background_image: return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull); + case eCSSProperty__moz_background_inline_policy: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kBackgroundInlinePolicyKTable); case eCSSProperty__moz_background_origin: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundOriginKTable); @@ -4247,9 +4250,10 @@ PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsCSSDeclaration* aDe } // Background properties not settable from the shorthand get reset to their initial value - const PRInt32 numResetProps = 2; + static const PRInt32 numResetProps = 3; static const nsCSSProperty kBackgroundResetIDs[numResetProps] = { eCSSProperty__moz_background_clip, + eCSSProperty__moz_background_inline_policy, eCSSProperty__moz_background_origin }; diff --git a/mozilla/layout/style/nsCSSPropList.h b/mozilla/layout/style/nsCSSPropList.h index 7c13710474a..e4b7d71d127 100644 --- a/mozilla/layout/style/nsCSSPropList.h +++ b/mozilla/layout/style/nsCSSPropList.h @@ -112,6 +112,7 @@ CSS_PROP(background-attachment, background_attachment, BackgroundAttachment, NS_ 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-inline-policy, _moz_background_inline_policy, MozBackgroundInlinePolicy, 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) diff --git a/mozilla/layout/style/nsCSSProps.cpp b/mozilla/layout/style/nsCSSProps.cpp index a65987c061d..f316aa0720e 100644 --- a/mozilla/layout/style/nsCSSProps.cpp +++ b/mozilla/layout/style/nsCSSProps.cpp @@ -234,6 +234,13 @@ const PRInt32 nsCSSProps::kBackgroundClipKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundInlinePolicyKTable[] = { + eCSSKeyword_each_box, NS_STYLE_BG_INLINE_POLICY_EACH_BOX, + eCSSKeyword_continuous, NS_STYLE_BG_INLINE_POLICY_CONTINUOUS, + eCSSKeyword_bounding_box, NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX, + -1,-1 +}; + const PRInt32 nsCSSProps::kBackgroundOriginKTable[] = { eCSSKeyword_border, NS_STYLE_BG_ORIGIN_BORDER, eCSSKeyword_padding, NS_STYLE_BG_ORIGIN_PADDING, @@ -942,6 +949,9 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty__moz_background_clip: return SearchKeywordTable(aValue, kBackgroundClipKTable); + case eCSSProperty__moz_background_inline_policy: + return SearchKeywordTable(aValue, kBackgroundInlinePolicyKTable); + case eCSSProperty__moz_background_origin: return SearchKeywordTable(aValue, kBackgroundOriginKTable); diff --git a/mozilla/layout/style/nsCSSProps.h b/mozilla/layout/style/nsCSSProps.h index bd77f3ae95b..1508a903d42 100644 --- a/mozilla/layout/style/nsCSSProps.h +++ b/mozilla/layout/style/nsCSSProps.h @@ -89,6 +89,7 @@ public: static const PRInt32 kBackgroundAttachmentKTable[]; static const PRInt32 kBackgroundClipKTable[]; static const PRInt32 kBackgroundColorKTable[]; + static const PRInt32 kBackgroundInlinePolicyKTable[]; static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; static const PRInt32 kBorderCollapseKTable[]; diff --git a/mozilla/layout/style/nsCSSStruct.cpp b/mozilla/layout/style/nsCSSStruct.cpp index d41dcc66aa1..6140b031800 100644 --- a/mozilla/layout/style/nsCSSStruct.cpp +++ b/mozilla/layout/style/nsCSSStruct.cpp @@ -168,7 +168,9 @@ nsCSSColor::nsCSSColor(const nsCSSColor& aCopy) mBackPositionX(aCopy.mBackPositionX), mBackPositionY(aCopy.mBackPositionY), mBackClip(aCopy.mBackClip), - mBackOrigin(aCopy.mBackOrigin) + mBackOrigin(aCopy.mBackOrigin), + mBackInlinePolicy(aCopy.mBackInlinePolicy) + { MOZ_COUNT_CTOR(nsCSSColor); } @@ -199,6 +201,7 @@ void nsCSSColor::List(FILE* out, PRInt32 aIndent) const mBackPositionY.AppendToString(buffer, eCSSProperty_background_y_position); mBackClip.AppendToString(buffer, eCSSProperty__moz_background_clip); mBackOrigin.AppendToString(buffer, eCSSProperty__moz_background_origin); + mBackInlinePolicy.AppendToString(buffer, eCSSProperty__moz_background_inline_policy); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } #endif @@ -1476,7 +1479,8 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_ENSURE(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor = aValue; break; @@ -1488,6 +1492,7 @@ nsCSSDeclaration::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy = aValue; break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -2319,7 +2324,8 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { CSS_ENSURE_IMPORTANT(Color) { @@ -2333,6 +2339,7 @@ nsCSSDeclaration::SetValueImportant(nsCSSProperty aProperty) 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_CASE_IMPORTANT(eCSSProperty__moz_background_inline_policy, Color, mBackInlinePolicy); CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -3285,7 +3292,8 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_CHECK(Color) { switch (aProperty) { case eCSSProperty_color: theColor->mColor.Reset(); break; @@ -3297,6 +3305,7 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) 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; + case eCSSProperty__moz_background_inline_policy: theColor->mBackInlinePolicy.Reset(); break; CSS_BOGUS_DEFAULT; // make compiler happy } } @@ -4117,7 +4126,8 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: case eCSSProperty__moz_background_clip: - case eCSSProperty__moz_background_origin: { + case eCSSProperty__moz_background_origin: + case eCSSProperty__moz_background_inline_policy: { CSS_VARONSTACK_GET(Color); if (nsnull != theColor) { switch (aProperty) { @@ -4130,6 +4140,7 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) 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; + case eCSSProperty__moz_background_inline_policy: aValue = theColor->mBackInlinePolicy; break; CSS_BOGUS_DEFAULT; // make compiler happy } } diff --git a/mozilla/layout/style/nsCSSStruct.h b/mozilla/layout/style/nsCSSStruct.h index 915aa6c7fd1..5b9b17a9620 100644 --- a/mozilla/layout/style/nsCSSStruct.h +++ b/mozilla/layout/style/nsCSSStruct.h @@ -177,6 +177,7 @@ struct nsCSSColor : public nsCSSStruct { nsCSSValue mBackPositionY; nsCSSValue mBackClip; nsCSSValue mBackOrigin; + nsCSSValue mBackInlinePolicy; }; struct nsRuleDataColor : public nsCSSColor { diff --git a/mozilla/layout/style/nsCSSStyleRule.cpp b/mozilla/layout/style/nsCSSStyleRule.cpp index ad83c0e1430..21dfe693487 100644 --- a/mozilla/layout/style/nsCSSStyleRule.cpp +++ b/mozilla/layout/style/nsCSSStyleRule.cpp @@ -2142,6 +2142,10 @@ MapColorForDeclaration(nsCSSDeclaration* aDecl, const nsStyleStructID& aID, nsRu if (aColor.mBackClip.GetUnit() == eCSSUnit_Null && ourColor->mBackClip.GetUnit() != eCSSUnit_Null) aColor.mBackClip = ourColor->mBackClip; + // background-inline-policy: enum, inherit + if (aColor.mBackInlinePolicy.GetUnit() == eCSSUnit_Null && ourColor->mBackInlinePolicy.GetUnit() != eCSSUnit_Null) + aColor.mBackInlinePolicy = ourColor->mBackInlinePolicy; + // background-origin: enum, inherit if (aColor.mBackOrigin.GetUnit() == eCSSUnit_Null && ourColor->mBackOrigin.GetUnit() != eCSSUnit_Null) aColor.mBackOrigin = ourColor->mBackOrigin; diff --git a/mozilla/layout/style/nsComputedDOMStyle.cpp b/mozilla/layout/style/nsComputedDOMStyle.cpp index 6356a06061d..da99794db63 100644 --- a/mozilla/layout/style/nsComputedDOMStyle.cpp +++ b/mozilla/layout/style/nsComputedDOMStyle.cpp @@ -762,6 +762,30 @@ nsComputedDOMStyle::GetBackgroundImage(nsIFrame *aFrame, return CallQueryInterface(val, aValue); } +nsresult +nsComputedDOMStyle::GetBackgroundInlinePolicy(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 policy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS; + if (background) { + policy = background->mBackgroundInlinePolicy; + } + + const nsAFlatCString& backgroundPolicy = + nsCSSProps::SearchKeywordTable(policy, + nsCSSProps::kBackgroundInlinePolicyKTable); + + val->SetIdent(backgroundPolicy); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue) @@ -3599,6 +3623,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) COMPUTED_STYLE_MAP_ENTRY(appearance, Appearance), COMPUTED_STYLE_MAP_ENTRY(_moz_background_clip, BackgroundClip), + COMPUTED_STYLE_MAP_ENTRY(_moz_background_inline_policy, BackgroundInlinePolicy), COMPUTED_STYLE_MAP_ENTRY(_moz_background_origin, BackgroundOrigin), COMPUTED_STYLE_MAP_ENTRY(binding, Binding), COMPUTED_STYLE_MAP_ENTRY(border_bottom_colors, BorderBottomColors), diff --git a/mozilla/layout/style/nsComputedDOMStyle.h b/mozilla/layout/style/nsComputedDOMStyle.h index 22f982d1fab..cdcd52b9dd3 100644 --- a/mozilla/layout/style/nsComputedDOMStyle.h +++ b/mozilla/layout/style/nsComputedDOMStyle.h @@ -177,6 +177,7 @@ private: nsresult GetBackgroundImage(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundRepeat(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundClip(nsIFrame *aFrame, nsIDOMCSSValue** aValue); + nsresult GetBackgroundInlinePolicy(nsIFrame *aFrame, nsIDOMCSSValue** aValue); nsresult GetBackgroundOrigin(nsIFrame *aFrame, nsIDOMCSSValue** aValue); /* Padding properties */ diff --git a/mozilla/layout/style/nsRuleNode.cpp b/mozilla/layout/style/nsRuleNode.cpp index 3fac10a7c1c..daa48117cd7 100644 --- a/mozilla/layout/style/nsRuleNode.cpp +++ b/mozilla/layout/style/nsRuleNode.cpp @@ -892,6 +892,7 @@ static const PropertyCheckData BackgroundCheckProperties[] = { CHECKDATA_PROP(nsRuleDataColor, mBackClip, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackColor, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackImage, CHECKDATA_VALUE, PR_FALSE), + CHECKDATA_PROP(nsRuleDataColor, mBackInlinePolicy, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackOrigin, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackPositionX, CHECKDATA_VALUE, PR_FALSE), CHECKDATA_PROP(nsRuleDataColor, mBackPositionY, CHECKDATA_VALUE, PR_FALSE) @@ -3254,6 +3255,17 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct, bg->mBackgroundClip = NS_STYLE_BG_CLIP_BORDER; } + // background-inline-policy: enum, inherit, initial + if (eCSSUnit_Enumerated == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = colorData.mBackInlinePolicy.GetIntValue(); + } + else if (eCSSUnit_Inherit == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = parentBG->mBackgroundInlinePolicy; + } + else if (eCSSUnit_Initial == colorData.mBackInlinePolicy.GetUnit()) { + bg->mBackgroundInlinePolicy = NS_STYLE_BG_INLINE_POLICY_CONTINUOUS; + } + // background-origin: enum, inherit, initial if (eCSSUnit_Enumerated == colorData.mBackOrigin.GetUnit()) { bg->mBackgroundOrigin = colorData.mBackOrigin.GetIntValue(); diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp index 6bbf26a5e9d..8f9563f8dbd 100644 --- a/mozilla/layout/style/nsStyleStruct.cpp +++ b/mozilla/layout/style/nsStyleStruct.cpp @@ -971,27 +971,30 @@ nsChangeHint nsStyleColor::CalcDifference(const nsStyleColor& aOther) const // nsStyleBackground::nsStyleBackground(nsIPresContext* aPresContext) + : mBackgroundFlags(NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE), + mBackgroundAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL), + mBackgroundClip(NS_STYLE_BG_CLIP_BORDER), + mBackgroundInlinePolicy(NS_STYLE_BG_INLINE_POLICY_CONTINUOUS), + mBackgroundOrigin(NS_STYLE_BG_ORIGIN_PADDING), + mBackgroundRepeat(NS_STYLE_BG_REPEAT_XY), + mBackgroundXPosition(0), + mBackgroundYPosition(0) { - 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; } nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) + : mBackgroundFlags(aSource.mBackgroundFlags), + mBackgroundAttachment(aSource.mBackgroundAttachment), + mBackgroundClip(aSource.mBackgroundClip), + mBackgroundInlinePolicy(aSource.mBackgroundInlinePolicy), + mBackgroundOrigin(aSource.mBackgroundOrigin), + mBackgroundRepeat(aSource.mBackgroundRepeat), + mBackgroundColor(aSource.mBackgroundColor), + mBackgroundXPosition(aSource.mBackgroundXPosition), + mBackgroundYPosition(aSource.mBackgroundYPosition), + mBackgroundImage(aSource.mBackgroundImage) { - mBackgroundAttachment = aSource.mBackgroundAttachment; - mBackgroundFlags = aSource.mBackgroundFlags; - mBackgroundRepeat = aSource.mBackgroundRepeat; - mBackgroundClip = aSource.mBackgroundClip; - mBackgroundOrigin = aSource.mBackgroundOrigin; - mBackgroundColor = aSource.mBackgroundColor; - mBackgroundXPosition = aSource.mBackgroundXPosition; - mBackgroundYPosition = aSource.mBackgroundYPosition; - mBackgroundImage = aSource.mBackgroundImage; } nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const @@ -1009,6 +1012,7 @@ nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) (mBackgroundXPosition == aOther.mBackgroundXPosition) && (mBackgroundYPosition == aOther.mBackgroundYPosition) && (mBackgroundClip == aOther.mBackgroundClip) && + (mBackgroundInlinePolicy == aOther.mBackgroundInlinePolicy) && (mBackgroundOrigin == aOther.mBackgroundOrigin) && (mBackgroundImage == aOther.mBackgroundImage)) return NS_STYLE_HINT_NONE; diff --git a/mozilla/layout/style/nsStyleStruct.h b/mozilla/layout/style/nsStyleStruct.h index 493c96f914b..0fbd1df1ddf 100644 --- a/mozilla/layout/style/nsStyleStruct.h +++ b/mozilla/layout/style/nsStyleStruct.h @@ -158,23 +158,32 @@ struct nsStyleBackground : public nsStyleStruct { nsChangeHint CalcDifference(const nsStyleBackground& aOther) const; // 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. + // inheritance so we only have 3 bytes to fit these 6 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 + PRUint8 mBackgroundFlags; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundAttachment : 4; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundClip : 3; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundInlinePolicy : 2; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundOrigin : 3; // [reset] See nsStyleConsts.h + PRUint8 mBackgroundRepeat : 4; // [reset] See nsStyleConsts.h nscolor mBackgroundColor; // [reset] nscoord mBackgroundXPosition; // [reset] nscoord mBackgroundYPosition; // [reset] nsString mBackgroundImage; // [reset] absolute url string - PRBool BackgroundIsTransparent() const {return (mBackgroundFlags & - (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE)) == - (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE);} + PRBool IsTransparent() const + { + return (mBackgroundFlags & + (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE)) == + (NS_STYLE_BG_COLOR_TRANSPARENT | NS_STYLE_BG_IMAGE_NONE); + } + + PRBool IsPositioned() const + { + return mBackgroundXPosition != 0 || mBackgroundYPosition != 0; + } }; #define BORDER_COLOR_DEFINED 0x80