Correcting our background painting code per the latest CSS specs. By default, backgrounds should be painted to the border

area, and not the padding area as per the CSS 2 Errata, CSS2.1 and CSS3.  Also, implementing the CSS3 'background-clip'
and 'background-origin' properties (currently with -moz- prefixes) to control this behavior.
Bug 162252, r=dbaron sr=roc+moz
This commit is contained in:
caillon%returnzero.com 2002-10-08 10:24:53 +00:00
parent 35c5cded43
commit 5ba9439c07
71 changed files with 1432 additions and 792 deletions

View File

@ -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());

View File

@ -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<nsIPrefService> prefService =
do_GetService(NS_PREFSERVICE_CONTRACTID);
NS_ENSURE_TRUE(prefService, NS_ERROR_FAILURE);
nsCOMPtr<nsIPrefBranch> 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

View File

@ -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
}
}

View File

@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct {
nsCSSValue mBackAttachment;
nsCSSValue mBackPositionX;
nsCSSValue mBackPositionY;
nsCSSValue mBackClip;
nsCSSValue mBackOrigin;
};
struct nsCSSShadow {

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct {
nsCSSValue mBackAttachment;
nsCSSValue mBackPositionX;
nsCSSValue mBackPositionY;
nsCSSValue mBackClip;
nsCSSValue mBackOrigin;
};
struct nsCSSShadow {

View File

@ -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;

View File

@ -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),

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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[];

View File

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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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<imgIRequest> 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<imgIRequest> req;
nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req));
nsCOMPtr<imgIContainer> 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<imgIContainer> 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<nsIScrollableFrame> 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<nsIPresShell> 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<nsIScrollableFrame> 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<nsIPresShell> 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<nsIAtom> 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<nsIAtom> 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);
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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<imgIRequest> 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<imgIRequest> req;
nsresult rv = aPresContext->LoadImage(aColor.mBackgroundImage, pBGFrame, getter_AddRefs(req));
nsCOMPtr<imgIContainer> 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<imgIContainer> 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<nsIScrollableFrame> 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<nsIPresShell> 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<nsIScrollableFrame> 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<nsIPresShell> 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<nsIAtom> 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<nsIAtom> 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);
}

View File

@ -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,

View File

@ -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
}

View File

@ -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);

View File

@ -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()) {

View File

@ -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();

View File

@ -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,

View File

@ -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
}
}

View File

@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct {
nsCSSValue mBackAttachment;
nsCSSValue mBackPositionX;
nsCSSValue mBackPositionY;
nsCSSValue mBackClip;
nsCSSValue mBackOrigin;
};
struct nsCSSShadow {

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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[];

View File

@ -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
}
}

View File

@ -164,6 +164,8 @@ struct nsCSSColor : public nsCSSStruct {
nsCSSValue mBackAttachment;
nsCSSValue mBackPositionX;
nsCSSValue mBackPositionY;
nsCSSValue mBackClip;
nsCSSValue mBackOrigin;
};
struct nsCSSShadow {

View File

@ -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;

View File

@ -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),

View File

@ -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);

View File

@ -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());

View File

@ -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;

View File

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

View File

@ -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,

View File

@ -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
}

View File

@ -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);

View File

@ -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()) {

View File

@ -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,

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);