--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1000,17 +1000,17 @@ nsCSSRendering::PaintFocus(nsPresContext
//----------------------------------------------------------------------
/**
* Helper for ComputeObjectAnchorPoint; parameters are the same as for
* that function, except they're for a single coordinate / a single size
* dimension. (so, x/width vs. y/height)
*/
-typedef nsStyleBackground::Position::PositionCoord PositionCoord;
+typedef nsStyleImageLayers::Position::PositionCoord PositionCoord;
static void
ComputeObjectAnchorCoord(const PositionCoord& aCoord,
const nscoord aOriginBounds,
const nscoord aImageSize,
nscoord* aTopLeftCoord,
nscoord* aAnchorPointCoord)
{
*aAnchorPointCoord = aCoord.mLength;
@@ -1024,17 +1024,17 @@ ComputeObjectAnchorCoord(const PositionC
// The anchor-point doesn't care about our image's size; just the size
// of the region we're rendering into.
*aAnchorPointCoord += NSToCoordRound(aCoord.mPercent * aOriginBounds);
}
}
void
nsImageRenderer::ComputeObjectAnchorPoint(
- const nsStyleBackground::Position& aPos,
+ const nsStyleImageLayers::Position& aPos,
const nsSize& aOriginBounds,
const nsSize& aImageSize,
nsPoint* aTopLeft,
nsPoint* aAnchorPoint)
{
ComputeObjectAnchorCoord(aPos.mXPosition,
aOriginBounds.width, aImageSize.width,
&aTopLeft->x, &aAnchorPoint->x);
@@ -1742,20 +1742,23 @@ SetupDirtyRects(const nsRect& aBGClipAre
*aDirtyRectGfx = nsLayoutUtils::RectToGfxRect(*aDirtyRect, aAppUnitsPerPixel);
NS_WARN_IF_FALSE(aDirtyRect->IsEmpty() || !aDirtyRectGfx->IsEmpty(),
"converted dirty rect should not be empty");
MOZ_ASSERT(!aDirtyRect->IsEmpty() || aDirtyRectGfx->IsEmpty(),
"second should be empty if first is");
}
/* static */ void
-nsCSSRendering::GetBackgroundClip(const nsStyleBackground::Layer& aLayer,
- nsIFrame* aForFrame, const nsStyleBorder& aBorder,
- const nsRect& aBorderArea, const nsRect& aCallerDirtyRect,
- bool aWillPaintBorder, nscoord aAppUnitsPerPixel,
+nsCSSRendering::GetBackgroundClip(const nsStyleImageLayers::Layer& aLayer,
+ nsIFrame* aForFrame,
+ const nsStyleBorder& aBorder,
+ const nsRect& aBorderArea,
+ const nsRect& aCallerDirtyRect,
+ bool aWillPaintBorder,
+ nscoord aAppUnitsPerPixel,
/* out */ BackgroundClipState* aClipState)
{
// Compute the outermost boundary of the area that might be painted.
// Same coordinate space as aBorderArea.
Sides skipSides = aForFrame->GetSkipSides();
nsRect clipBorderArea =
::BoxDecorationRectForBorder(aForFrame, aBorderArea, skipSides, &aBorder);
@@ -2894,19 +2897,19 @@ nsCSSRendering::PaintBackgroundWithSC(ns
bool drawBackgroundColor;
nscolor bgColor = DetermineBackgroundColor(aPresContext,
aBackgroundSC,
aForFrame,
drawBackgroundImage,
drawBackgroundColor);
+ const nsStyleImageLayers& layers = aBackgroundSC->StyleBackground()->mLayers;
// If we're drawing a specific layer, we don't want to draw the
// background color.
- const nsStyleBackground *bg = aBackgroundSC->StyleBackground();
if (drawBackgroundColor && aLayer >= 0) {
drawBackgroundColor = false;
}
// At this point, drawBackgroundImage and drawBackgroundColor are
// true if and only if we are actually supposed to paint an image or
// color into aDirtyRect, respectively.
if (!drawBackgroundImage && !drawBackgroundColor)
@@ -2931,17 +2934,17 @@ nsCSSRendering::PaintBackgroundWithSC(ns
BackgroundClipState clipState;
if (aBGClipRect) {
clipState.mBGClipArea = *aBGClipRect;
clipState.mCustomClip = true;
clipState.mHasRoundedCorners = false;
SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel,
&clipState.mDirtyRect, &clipState.mDirtyRectGfx);
} else {
- GetBackgroundClip(bg->BottomLayer(),
+ GetBackgroundClip(layers.BottomLayer(),
aForFrame, aBorder, aBorderArea,
aDirtyRect, (aFlags & PAINTBG_WILL_PAINT_BORDER), appUnitsPerPixel,
&clipState);
}
// If we might be using a background color, go ahead and set it now.
if (drawBackgroundColor && !isCanvasFrame)
ctx->SetColor(Color::FromABGR(bgColor));
@@ -2955,52 +2958,52 @@ nsCSSRendering::PaintBackgroundWithSC(ns
// this far.)
if (!drawBackgroundImage) {
if (!isCanvasFrame) {
DrawBackgroundColor(clipState, ctx, appUnitsPerPixel);
}
return DrawResult::SUCCESS;
}
- if (bg->mImageCount < 1) {
+ if (layers.mImageCount < 1) {
// Return if there are no background layers, all work from this point
// onwards happens iteratively on these.
return DrawResult::SUCCESS;
}
// Validate the layer range before we start iterating.
int32_t startLayer = aLayer;
int32_t nLayers = 1;
if (startLayer < 0) {
- startLayer = (int32_t)bg->mImageCount - 1;
- nLayers = bg->mImageCount;
+ startLayer = (int32_t)layers.mImageCount - 1;
+ nLayers = layers.mImageCount;
}
// Ensure we get invalidated for loads of the image. We need to do
// this here because this might be the only code that knows about the
// association of the style data with the frame.
if (aBackgroundSC != aForFrame->StyleContext()) {
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, bg, startLayer, nLayers) {
- aForFrame->AssociateImage(bg->mLayers[i].mImage, aPresContext);
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT_WITH_RANGE(i, layers, startLayer, nLayers) {
+ aForFrame->AssociateImage(layers.mLayers[i].mImage, aPresContext);
}
}
// The background color is rendered over the entire dirty area,
// even if the image isn't.
if (drawBackgroundColor && !isCanvasFrame) {
DrawBackgroundColor(clipState, ctx, appUnitsPerPixel);
}
if (drawBackgroundImage) {
bool clipSet = false;
uint8_t currentBackgroundClip = NS_STYLE_BG_CLIP_BORDER;
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, bg, bg->mImageCount - 1,
- nLayers + (bg->mImageCount -
- startLayer - 1)) {
- const nsStyleBackground::Layer &layer = bg->mLayers[i];
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT_WITH_RANGE(i, layers, layers.mImageCount - 1,
+ nLayers + (layers.mImageCount -
+ startLayer - 1)) {
+ const nsStyleImageLayers::Layer& layer = layers.mLayers[i];
if (!aBGClipRect) {
if (currentBackgroundClip != layer.mClip || !clipSet) {
currentBackgroundClip = layer.mClip;
// If clipSet is false that means this is the bottom layer and we
// already called GetBackgroundClip above and it stored its results
// in clipState.
if (clipSet) {
autoSR.Restore(); // reset the previous one
@@ -3062,17 +3065,17 @@ IsTransformed(nsIFrame* aForFrame, nsIFr
}
return false;
}
nsRect
nsCSSRendering::ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
- const nsStyleBackground::Layer& aLayer,
+ const nsStyleImageLayers::Layer& aLayer,
nsIFrame** aAttachedToFrame)
{
// Compute background origin area relative to aBorderArea now as we may need
// it to compute the effective image size for a CSS gradient.
nsRect bgPositioningArea;
nsIAtom* frameType = aForFrame->GetType();
nsIFrame* geometryFrame = aForFrame;
@@ -3167,53 +3170,53 @@ nsCSSRendering::ComputeBackgroundPositio
// Apply the CSS image sizing algorithm as it applies to background images.
// See http://www.w3.org/TR/css3-background/#the-background-size .
// aIntrinsicSize is the size that the background image 'would like to be'.
// It can be found by calling nsImageRenderer::ComputeIntrinsicSize.
static nsSize
ComputeDrawnSizeForBackground(const CSSSizeOrRatio& aIntrinsicSize,
const nsSize& aBgPositioningArea,
- const nsStyleBackground::Size& aLayerSize)
+ const nsStyleImageLayers::Size& aLayerSize)
{
// Size is dictated by cover or contain rules.
- if (aLayerSize.mWidthType == nsStyleBackground::Size::eContain ||
- aLayerSize.mWidthType == nsStyleBackground::Size::eCover) {
+ if (aLayerSize.mWidthType == nsStyleImageLayers::Size::eContain ||
+ aLayerSize.mWidthType == nsStyleImageLayers::Size::eCover) {
nsImageRenderer::FitType fitType =
- aLayerSize.mWidthType == nsStyleBackground::Size::eCover
+ aLayerSize.mWidthType == nsStyleImageLayers::Size::eCover
? nsImageRenderer::COVER
: nsImageRenderer::CONTAIN;
return nsImageRenderer::ComputeConstrainedSize(aBgPositioningArea,
aIntrinsicSize.mRatio,
fitType);
}
// No cover/contain constraint, use default algorithm.
CSSSizeOrRatio specifiedSize;
- if (aLayerSize.mWidthType == nsStyleBackground::Size::eLengthPercentage) {
+ if (aLayerSize.mWidthType == nsStyleImageLayers::Size::eLengthPercentage) {
specifiedSize.SetWidth(
aLayerSize.ResolveWidthLengthPercentage(aBgPositioningArea));
}
- if (aLayerSize.mHeightType == nsStyleBackground::Size::eLengthPercentage) {
+ if (aLayerSize.mHeightType == nsStyleImageLayers::Size::eLengthPercentage) {
specifiedSize.SetHeight(
aLayerSize.ResolveHeightLengthPercentage(aBgPositioningArea));
}
return nsImageRenderer::ComputeConcreteSize(specifiedSize,
aIntrinsicSize,
aBgPositioningArea);
}
nsBackgroundLayerState
nsCSSRendering::PrepareBackgroundLayer(nsPresContext* aPresContext,
nsIFrame* aForFrame,
uint32_t aFlags,
const nsRect& aBorderArea,
const nsRect& aBGClipRect,
- const nsStyleBackground::Layer& aLayer)
+ const nsStyleImageLayers::Layer& aLayer)
{
/*
* The properties we need to keep in mind when drawing background
* layers are:
*
* background-image
* background-repeat
* background-attachment
@@ -3367,17 +3370,17 @@ nsCSSRendering::PrepareBackgroundLayer(n
return state;
}
nsRect
nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsRect& aClipRect,
- const nsStyleBackground::Layer& aLayer,
+ const nsStyleImageLayers::Layer& aLayer,
uint32_t aFlags)
{
Sides skipSides = aForFrame->GetSkipSides();
nsRect borderArea =
::BoxDecorationRectForBackground(aForFrame, aBorderArea, skipSides);
nsBackgroundLayerState state =
PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, borderArea,
aClipRect, aLayer);
@@ -4851,17 +4854,17 @@ nsImageRenderer::ComputeIntrinsicSize()
break;
}
case eStyleImageType_Element:
{
// XXX element() should have the width/height of the referenced element,
// and that element's ratio, if it matches. If it doesn't match, it
// should have no width/height or ratio. See element() in CSS images:
// <http://dev.w3.org/csswg/css-images-4/#element-notation>.
- // Make sure to change nsStyleBackground::Size::DependsOnFrameSize
+ // Make sure to change nsStyleImageLayers::Size::DependsOnFrameSize
// when fixing this!
if (mPaintServerFrame) {
// SVG images have no intrinsic size
if (!mPaintServerFrame->IsFrameOfType(nsIFrame::eSVG)) {
// The intrinsic image size for a generic nsIFrame paint server is
// the union of the border-box rects of all of its continuations,
// rounded to device pixels.
int32_t appUnitsPerDevPixel =
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -170,17 +170,17 @@ public:
* @param aAnchorPoint [out] A point which should be pixel-aligned by
* nsLayoutUtils::DrawImage. This is the same as aTopLeft, unless
* CSS specifies a percentage (including 'right' or 'bottom'), in
* which case it's that percentage within of aOriginBounds. So
* 'right' would set aAnchorPoint.x to aOriginBounds.XMost().
*
* Points are returned relative to aOriginBounds.
*/
- static void ComputeObjectAnchorPoint(const nsStyleBackground::Position& aPos,
+ static void ComputeObjectAnchorPoint(const nsStyleImageLayers::Position& aPos,
const nsSize& aOriginBounds,
const nsSize& aImageSize,
nsPoint* aTopLeft,
nsPoint* aAnchorPoint);
/**
* Compute the size of the rendered image using either the 'cover' or
* 'contain' constraints (aFitType).
@@ -531,26 +531,26 @@ struct nsCSSRendering {
nsIFrame* aFrame,
bool& aDrawBackgroundImage,
bool& aDrawBackgroundColor);
static nsRect
ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
- const nsStyleBackground::Layer& aLayer,
+ const nsStyleImageLayers::Layer& aLayer,
nsIFrame** aAttachedToFrame);
static nsBackgroundLayerState
PrepareBackgroundLayer(nsPresContext* aPresContext,
nsIFrame* aForFrame,
uint32_t aFlags,
const nsRect& aBorderArea,
const nsRect& aBGClipRect,
- const nsStyleBackground::Layer& aLayer);
+ const nsStyleImageLayers::Layer& aLayer);
struct BackgroundClipState {
nsRect mBGClipArea; // Affected by mClippedRadii
nsRect mAdditionalBGClipArea; // Not affected by mClippedRadii
nsRect mDirtyRect;
gfxRect mDirtyRectGfx;
nscoord mRadii[8];
@@ -559,17 +559,17 @@ struct nsCSSRendering {
bool mHasAdditionalBGClipArea;
// Whether we are being asked to draw with a caller provided background
// clipping area. If this is true we also disable rounded corners.
bool mCustomClip;
};
static void
- GetBackgroundClip(const nsStyleBackground::Layer& aLayer,
+ GetBackgroundClip(const nsStyleImageLayers::Layer& aLayer,
nsIFrame* aForFrame, const nsStyleBorder& aBorder, const nsRect& aBorderArea,
const nsRect& aCallerDirtyRect, bool aWillPaintBorder,
nscoord aAppUnitsPerPixel,
/* out */ BackgroundClipState* aClipState);
/**
* Render the background for an element using css rendering rules
* for backgrounds.
@@ -623,17 +623,17 @@ struct nsCSSRendering {
* Returns the rectangle covered by the given background layer image, taking
* into account background positioning, sizing, and repetition, but not
* clipping.
*/
static nsRect GetBackgroundLayerRect(nsPresContext* aPresContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsRect& aClipRect,
- const nsStyleBackground::Layer& aLayer,
+ const nsStyleImageLayers::Layer& aLayer,
uint32_t aFlags);
/**
* Called when we start creating a display list. The frame tree will not
* change until a matching EndFrameTreeLocked is called.
*/
static void BeginFrameTreesLocked();
/**
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2250,17 +2250,17 @@ nsDisplayBackgroundImage::GetDestAreaInt
{
if (!mBackgroundStyle) {
return nsRect();
}
nsPresContext* presContext = mFrame->PresContext();
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
- const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer& layer = mBackgroundStyle->mLayers.mLayers[mLayer];
nsBackgroundLayerState state =
nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
borderArea, borderArea, layer);
return state.mDestArea;
}
nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
@@ -2291,17 +2291,17 @@ static nsStyleContext* GetBackgroundStyl
sc = aFrame->StyleContext();
}
return sc;
}
/* static */ void
SetBackgroundClipRegion(DisplayListClipState::AutoSaveRestore& aClipState,
nsIFrame* aFrame, const nsPoint& aToReferenceFrame,
- const nsStyleBackground::Layer& aLayer,
+ const nsStyleImageLayers::Layer& aLayer,
bool aWillPaintBorder)
{
nsRect borderBox = nsRect(aToReferenceFrame, aFrame->GetSize());
nsCSSRendering::BackgroundClipState clip;
nsCSSRendering::GetBackgroundClip(aLayer, aFrame, *aFrame->StyleBorder(),
borderBox, borderBox, aWillPaintBorder,
aFrame->PresContext()->AppUnitsPerDevPixel(),
@@ -2397,28 +2397,28 @@ nsDisplayBackgroundImage::AppendBackgrou
aList->AppendToTop(&bgItemList);
return false;
}
bool needBlendContainer = false;
// Passing bg == nullptr in this macro will result in one iteration with
// i = 0.
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
- if (bg->mLayers[i].mImage.IsEmpty()) {
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, bg->mLayers) {
+ if (bg->mLayers.mLayers[i].mImage.IsEmpty()) {
continue;
}
- if (bg->mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
+ if (bg->mLayers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
needBlendContainer = true;
}
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
if (!aBuilder->IsForEventDelivery()) {
- const nsStyleBackground::Layer& layer = bg->mLayers[i];
+ const nsStyleImageLayers::Layer& layer = bg->mLayers.mLayers[i];
SetBackgroundClipRegion(clipState, aFrame, toRef,
layer, willPaintBorder);
}
nsDisplayBackgroundImage* bgItem =
new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bg);
bgItemList.AppendNewToTop(bgItem);
}
@@ -2466,23 +2466,23 @@ static bool RoundedRectContainsRect(cons
bool
nsDisplayBackgroundImage::IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
const nsRect& aClipRect,
gfxRect* aDestRect)
{
if (!mBackgroundStyle)
return false;
- if (mBackgroundStyle->mLayers.Length() != 1)
+ if (mBackgroundStyle->mLayers.mLayers.Length() != 1)
return false;
nsPresContext* presContext = mFrame->PresContext();
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
- const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mLayers.mLayers[mLayer];
if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED)
return false;
nsBackgroundLayerState state =
nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
borderArea, aClipRect, layer);
nsImageRenderer* imageRenderer = &state.mImageRenderer;
@@ -2494,18 +2494,18 @@ nsDisplayBackgroundImage::IsSingleFixedP
*aDestRect = nsLayoutUtils::RectToGfxRect(state.mFillArea, appUnitsPerDevPixel);
return true;
}
bool
nsDisplayBackgroundImage::IsNonEmptyFixedImage() const
{
- return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
- !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
+ return mBackgroundStyle->mLayers.mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
+ !mBackgroundStyle->mLayers.mLayers[mLayer].mImage.IsEmpty();
}
bool
nsDisplayBackgroundImage::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
{
// APZ needs background-attachment:fixed images layerized for correctness.
RefPtr<LayerManager> layerManager = aBuilder->GetWidgetLayerManager();
if (!nsLayoutUtils::UsesAsyncScrolling(mFrame) &&
@@ -2524,17 +2524,17 @@ nsDisplayBackgroundImage::CanOptimizeToI
{
if (!mBackgroundStyle) {
return false;
}
nsPresContext* presContext = mFrame->PresContext();
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
- const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mLayers.mLayers[mLayer];
nsBackgroundLayerState state =
nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
borderArea, borderArea, layer);
nsImageRenderer* imageRenderer = &state.mImageRenderer;
// We only care about images here, not gradients.
if (!imageRenderer->IsRasterImage()) {
return false;
@@ -2594,17 +2594,17 @@ nsDisplayBackgroundImage::ShouldCreateOw
{
nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(mFrame);
if (ActiveLayerTracker::IsStyleAnimated(aBuilder, backgroundStyleFrame,
eCSSProperty_background_position)) {
return WHENEVER_POSSIBLE;
}
if (nsLayoutUtils::AnimatedImageLayersEnabled() && mBackgroundStyle) {
- const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mLayers.mLayers[mLayer];
const nsStyleImage* image = &layer.mImage;
if (image->GetType() == eStyleImageType_Image) {
imgIRequest* imgreq = image->GetImageData();
nsCOMPtr<imgIContainer> image;
if (NS_SUCCEEDED(imgreq->GetImage(getter_AddRefs(image))) && image) {
bool animated = false;
if (NS_SUCCEEDED(image->GetAnimated(&animated)) && animated) {
return WHENEVER_POSSIBLE;
@@ -2792,17 +2792,17 @@ nsDisplayBackgroundImage::GetOpaqueRegio
// For NS_STYLE_BOX_DECORATION_BREAK_SLICE, don't try to optimize here, since
// this could easily lead to O(N^2) behavior inside InlineBackgroundData,
// which expects frames to be sent to it in content order, not reverse
// content order which we'll produce here.
// Of course, if there's only one frame in the flow, it doesn't matter.
if (mFrame->StyleBorder()->mBoxDecorationBreak ==
NS_STYLE_BOX_DECORATION_BREAK_CLONE ||
(!mFrame->GetPrevContinuation() && !mFrame->GetNextContinuation())) {
- const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer& layer = mBackgroundStyle->mLayers.mLayers[mLayer];
if (layer.mImage.IsOpaque() && layer.mBlendMode == NS_STYLE_BLEND_NORMAL) {
nsPresContext* presContext = mFrame->PresContext();
result = GetInsideClipRegion(this, presContext, layer.mClip, mBounds, aSnap);
}
}
return result;
}
@@ -2821,34 +2821,34 @@ nsDisplayBackgroundImage::GetPositioning
{
if (!mBackgroundStyle) {
return nsRect();
}
nsIFrame* attachedToFrame;
return nsCSSRendering::ComputeBackgroundPositioningArea(
mFrame->PresContext(), mFrame,
nsRect(ToReferenceFrame(), mFrame->GetSize()),
- mBackgroundStyle->mLayers[mLayer],
+ mBackgroundStyle->mLayers.mLayers[mLayer],
&attachedToFrame) + ToReferenceFrame();
}
bool
nsDisplayBackgroundImage::RenderingMightDependOnPositioningAreaSizeChange()
{
if (!mBackgroundStyle)
return false;
nscoord radii[8];
if (mFrame->GetBorderRadii(radii)) {
// A change in the size of the positioning area might change the position
// of the rounded corners.
return true;
}
- const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mLayers.mLayers[mLayer];
if (layer.RenderingMightDependOnPositioningAreaSizeChange()) {
return true;
}
return false;
}
static void CheckForBorderItem(nsDisplayItem *aItem, uint32_t& aFlags)
{
@@ -2914,17 +2914,17 @@ void nsDisplayBackgroundImage::ComputeIn
if (!mDestArea.IsEqualInterior(geometry->mDestArea)) {
// Dest area changed in a way that could cause everything to change,
// so invalidate everything (both old and new painting areas).
aInvalidRegion->Or(bounds, geometry->mBounds);
NotifyRenderingChanged();
return;
}
if (aBuilder->ShouldSyncDecodeImages()) {
- const nsStyleImage& image = mBackgroundStyle->mLayers[mLayer].mImage;
+ const nsStyleImage& image = mBackgroundStyle->mLayers.mLayers[mLayer].mImage;
if (image.GetType() == eStyleImageType_Image &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
aInvalidRegion->Or(*aInvalidRegion, bounds);
NotifyRenderingChanged();
}
}
if (!bounds.IsEqualInterior(geometry->mBounds)) {
@@ -2960,17 +2960,17 @@ nsDisplayBackgroundImage::GetBoundsInter
// async scrolling could reveal additional areas of the image, so don't
// clip it beyond clipping to the document's viewport.
nsIFrame* rootFrame = presContext->PresShell()->GetRootFrame();
nsRect rootRect = rootFrame->GetRectRelativeToSelf();
if (nsLayoutUtils::TransformRect(rootFrame, mFrame, rootRect) == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
clipRect = rootRect + aBuilder->ToReferenceFrame(mFrame);
}
}
- const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
+ const nsStyleImageLayers::Layer& layer = mBackgroundStyle->mLayers.mLayers[mLayer];
return nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
borderBox, clipRect, layer,
aBuilder->GetBackgroundPaintFlags());
}
uint32_t
nsDisplayBackgroundImage::GetPerFrameKey()
{
@@ -3200,17 +3200,17 @@ nsDisplayBackgroundColor::GetOpaqueRegio
return nsRegion();
}
if (!mBackgroundStyle)
return nsRegion();
*aSnap = true;
- const nsStyleBackground::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
+ const nsStyleImageLayers::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
nsPresContext* presContext = mFrame->PresContext();
return nsDisplayBackgroundImage::GetInsideClipRegion(this, presContext, bottomLayer.mClip, borderBox, aSnap);
}
bool
nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
{
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3973,31 +3973,31 @@ ComputeConcreteObjectSize(const nsSize&
default:
MOZ_ASSERT_UNREACHABLE("Unexpected enum value for 'object-fit'");
return aConstraintSize; // fall back to (default) 'fill' behavior
}
}
// (Helper for HasInitialObjectFitAndPosition, to check
// each "object-position" coord.)
-typedef nsStyleBackground::Position::PositionCoord PositionCoord;
+typedef nsStyleImageLayers::Position::PositionCoord PositionCoord;
static bool
IsCoord50Pct(const PositionCoord& aCoord)
{
return (aCoord.mLength == 0 &&
aCoord.mHasPercent &&
aCoord.mPercent == 0.5f);
}
// Indicates whether the given nsStylePosition has the initial values
// for the "object-fit" and "object-position" properties.
static bool
HasInitialObjectFitAndPosition(const nsStylePosition* aStylePos)
{
- const nsStyleBackground::Position& objectPos = aStylePos->mObjectPosition;
+ const nsStyleImageLayers::Position& objectPos = aStylePos->mObjectPosition;
return aStylePos->mObjectFit == NS_STYLE_OBJECT_FIT_FILL &&
IsCoord50Pct(objectPos.mXPosition) &&
IsCoord50Pct(objectPos.mYPosition);
}
/* static */ nsRect
nsLayoutUtils::ComputeObjectDestRect(const nsRect& aConstraintRect,
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -503,21 +503,22 @@ nsCanvasFrame::BuildDisplayList(nsDispla
if (!bg) {
return;
}
bool needBlendContainer = false;
// Create separate items for each background layer.
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
- if (bg->mLayers[i].mImage.IsEmpty()) {
+ const nsStyleImageLayers& layers = bg->mLayers;
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, layers) {
+ if (layers.mLayers[i].mImage.IsEmpty()) {
continue;
}
- if (bg->mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
+ if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
needBlendContainer = true;
}
aLists.BorderBackground()->AppendNewToTop(
new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, i, bg));
}
if (needBlendContainer) {
aLists.BorderBackground()->AppendNewToTop(
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -254,18 +254,18 @@ public:
}
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override
{
// Put background-attachment:fixed canvas background images in their own
// compositing layer. Since we know their background painting area can't
// change (unless the viewport size itself changes), async scrolling
// will work well.
- return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
- !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
+ return mBackgroundStyle->mLayers.mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
+ !mBackgroundStyle->mLayers.mLayers[mLayer].mImage.IsEmpty();
}
// We still need to paint a background color as well as an image for this item,
// so we can't support this yet.
virtual bool SupportsOptimizingToImage() override { return false; }
NS_DISPLAY_DECL_NAME("CanvasBackgroundImage", TYPE_CANVAS_BACKGROUND_IMAGE)
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -764,37 +764,39 @@ nsFrame::DidSetStyleContext(nsStyleConte
// backgrounds from some other frame's style data, and we don't want
// to clear those notifiers unless we have to. (They'll be reset
// when we paint, although we could miss a notification in that
// interval.)
const nsStyleBackground *oldBG = aOldStyleContext ?
aOldStyleContext->StyleBackground() :
nullptr;
const nsStyleBackground *newBG = StyleBackground();
+ const nsStyleImageLayers& oldBGLayers = oldBG->mLayers;
+ const nsStyleImageLayers& newBGLayers = newBG->mLayers;
if (oldBG) {
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, oldBG) {
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, oldBGLayers) {
// If there is an image in oldBG that's not in newBG, drop it.
- if (i >= newBG->mImageCount ||
- !oldBG->mLayers[i].mImage.ImageDataEquals(newBG->mLayers[i].mImage)) {
- const nsStyleImage& oldImage = oldBG->mLayers[i].mImage;
+ if (i >= newBGLayers.mImageCount ||
+ !oldBGLayers.mLayers[i].mImage.ImageDataEquals(newBGLayers.mLayers[i].mImage)) {
+ const nsStyleImage& oldImage = oldBGLayers.mLayers[i].mImage;
if (oldImage.GetType() != eStyleImageType_Image) {
continue;
}
imageLoader->DisassociateRequestFromFrame(oldImage.GetImageData(),
this);
}
}
}
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, newBG) {
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, newBGLayers) {
// If there is an image in newBG that's not in oldBG, add it.
- if (!oldBG || i >= oldBG->mImageCount ||
- !newBG->mLayers[i].mImage.ImageDataEquals(oldBG->mLayers[i].mImage)) {
- const nsStyleImage& newImage = newBG->mLayers[i].mImage;
+ if (!oldBG || i >= oldBGLayers.mImageCount ||
+ !newBGLayers.mLayers[i].mImage.ImageDataEquals(oldBGLayers.mLayers[i].mImage)) {
+ const nsStyleImage& newImage = newBGLayers.mLayers[i].mImage;
if (newImage.GetType() != eStyleImageType_Image) {
continue;
}
imageLoader->AssociateRequestToFrame(newImage.GetImageData(), this);
}
}
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -5691,17 +5691,17 @@ ScrollSnapHelper(SnappingEdgeCallback& a
const nsStyleDisplay* styleDisplay = f->StyleDisplay();
size_t coordCount = styleDisplay->mScrollSnapCoordinate.Length();
if (coordCount) {
nsRect frameRect = f->GetRect();
nsPoint offset = f->GetOffsetTo(aScrolledFrame);
nsRect edgesRect = nsRect(offset, frameRect.Size());
for (size_t coordNum = 0; coordNum < coordCount; coordNum++) {
- const nsStyleBackground::Position &coordPosition =
+ const nsStyleImageLayers::Position &coordPosition =
f->StyleDisplay()->mScrollSnapCoordinate[coordNum];
nsPoint coordPoint = edgesRect.TopLeft() - aScrollSnapDestination;
coordPoint += nsPoint(coordPosition.mXPosition.mLength,
coordPosition.mYPosition.mLength);
if (coordPosition.mXPosition.mHasPercent) {
coordPoint.x += NSToCoordRound(coordPosition.mXPosition.mPercent *
frameRect.width);
}
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2914,17 +2914,17 @@ StyleCoordToCSSValue(const nsStyleCoord&
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
return true;
}
static void
-SetPositionValue(const nsStyleBackground::Position& aPos, nsCSSValue& aCSSValue)
+SetPositionValue(const nsStyleImageLayers::Position& aPos, nsCSSValue& aCSSValue)
{
RefPtr<nsCSSValue::Array> posArray = nsCSSValue::Array::Create(4);
aCSSValue.SetArrayValue(posArray.get(), eCSSUnit_Array);
// NOTE: Array entries #0 and #2 here are intentionally left untouched, with
// eCSSUnit_Null. The purpose of these entries in our specified-style
// <position> representation is to store edge names. But for values
// extracted from computed style (which is what we're dealing with here),
@@ -3283,51 +3283,51 @@ StyleAnimationValue::ExtractComputedValu
break;
}
case eCSSProperty_background_position: {
const nsStyleBackground *bg =
static_cast<const nsStyleBackground*>(styleStruct);
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
- MOZ_ASSERT(bg->mPositionCount > 0, "unexpected count");
- for (uint32_t i = 0, i_end = bg->mPositionCount; i != i_end; ++i) {
+ MOZ_ASSERT(bg->mLayers.mPositionCount > 0, "unexpected count");
+ for (uint32_t i = 0, i_end = bg->mLayers.mPositionCount; i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
- SetPositionValue(bg->mLayers[i].mPosition, item->mValue);
+ SetPositionValue(bg->mLayers.mLayers[i].mPosition, item->mValue);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_BackgroundPosition);
break;
}
case eCSSProperty_background_size: {
const nsStyleBackground *bg =
static_cast<const nsStyleBackground*>(styleStruct);
nsAutoPtr<nsCSSValuePairList> result;
nsCSSValuePairList **resultTail = getter_Transfers(result);
- MOZ_ASSERT(bg->mSizeCount > 0, "unexpected count");
- for (uint32_t i = 0, i_end = bg->mSizeCount; i != i_end; ++i) {
+ MOZ_ASSERT(bg->mLayers.mSizeCount > 0, "unexpected count");
+ for (uint32_t i = 0, i_end = bg->mLayers.mSizeCount; i != i_end; ++i) {
nsCSSValuePairList *item = new nsCSSValuePairList;
*resultTail = item;
resultTail = &item->mNext;
- const nsStyleBackground::Size &size = bg->mLayers[i].mSize;
+ const nsStyleImageLayers::Size &size = bg->mLayers.mLayers[i].mSize;
switch (size.mWidthType) {
- case nsStyleBackground::Size::eContain:
- case nsStyleBackground::Size::eCover:
+ case nsStyleImageLayers::Size::eContain:
+ case nsStyleImageLayers::Size::eCover:
item->mXValue.SetIntValue(size.mWidthType,
eCSSUnit_Enumerated);
break;
- case nsStyleBackground::Size::eAuto:
+ case nsStyleImageLayers::Size::eAuto:
item->mXValue.SetAutoValue();
break;
- case nsStyleBackground::Size::eLengthPercentage:
+ case nsStyleImageLayers::Size::eLengthPercentage:
// XXXbz is there a good reason we can't just
// SetCalcValue(&size.mWidth, item->mXValue) here?
if (!size.mWidth.mHasPercent &&
// negative values must have come from calc()
size.mWidth.mLength >= 0) {
MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
"Shouldn't have mPercent");
nscoordToCSSValue(size.mWidth.mLength, item->mXValue);
@@ -3337,24 +3337,24 @@ StyleAnimationValue::ExtractComputedValu
item->mXValue.SetPercentValue(size.mWidth.mPercent);
} else {
SetCalcValue(&size.mWidth, item->mXValue);
}
break;
}
switch (size.mHeightType) {
- case nsStyleBackground::Size::eContain:
- case nsStyleBackground::Size::eCover:
+ case nsStyleImageLayers::Size::eContain:
+ case nsStyleImageLayers::Size::eCover:
// leave it null
break;
- case nsStyleBackground::Size::eAuto:
+ case nsStyleImageLayers::Size::eAuto:
item->mYValue.SetAutoValue();
break;
- case nsStyleBackground::Size::eLengthPercentage:
+ case nsStyleImageLayers::Size::eLengthPercentage:
// XXXbz is there a good reason we can't just
// SetCalcValue(&size.mHeight, item->mYValue) here?
if (!size.mHeight.mHasPercent &&
// negative values must have come from calc()
size.mHeight.mLength >= 0) {
MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
"Shouldn't have mPercent");
nscoordToCSSValue(size.mHeight.mLength, item->mYValue);
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -844,45 +844,49 @@ protected:
nsCSSValue& mColor;
nsCSSValueList* mImage;
nsCSSValuePairList* mRepeat;
nsCSSValueList* mAttachment;
nsCSSValueList* mClip;
nsCSSValueList* mOrigin;
nsCSSValueList* mPosition;
nsCSSValuePairList* mSize;
+ nsCSSValueList* mComposite;
+ nsCSSValueList* mMode;
BackgroundParseState(
nsCSSValue& aColor, nsCSSValueList* aImage, nsCSSValuePairList* aRepeat,
nsCSSValueList* aAttachment, nsCSSValueList* aClip,
nsCSSValueList* aOrigin, nsCSSValueList* aPosition,
- nsCSSValuePairList* aSize) :
+ nsCSSValuePairList* aSize, nsCSSValueList* aComposite,
+ nsCSSValueList* aMode) :
mColor(aColor), mImage(aImage), mRepeat(aRepeat),
mAttachment(aAttachment), mClip(aClip), mOrigin(aOrigin),
- mPosition(aPosition), mSize(aSize) {};
+ mPosition(aPosition), mSize(aSize), mComposite(aComposite),
+ mMode(aMode) {};
};
bool IsFunctionTokenValidForBackgroundImage(const nsCSSToken& aToken) const;
bool ParseBackgroundItem(BackgroundParseState& aState);
bool ParseValueList(nsCSSProperty aPropID); // a single value prop-id
- bool ParseBackgroundRepeat();
+ bool ParseBackgroundRepeat(nsCSSProperty aPropID);
bool ParseBackgroundRepeatValues(nsCSSValuePair& aValue);
- bool ParseBackgroundPosition();
+ bool ParseBackgroundPosition(nsCSSProperty aPropID);
// ParseBoxPositionValues parses the CSS 2.1 background-position syntax,
// which is still used by some properties. See ParsePositionValue
// for the css3-background syntax.
bool ParseBoxPositionValues(nsCSSValuePair& aOut, bool aAcceptsInherit,
bool aAllowExplicitCenter = true); // deprecated
// ParsePositionValue parses a CSS <position> value, which is used by
// the 'background-position' property.
bool ParsePositionValue(nsCSSValue& aOut);
- bool ParseBackgroundSize();
+ bool ParseBackgroundSize(nsCSSProperty aPropID);
bool ParseBackgroundSizeValues(nsCSSValuePair& aOut);
bool ParseBorderColor();
bool ParseBorderColors(nsCSSProperty aProperty);
void SetBorderImageInitialValues();
bool ParseBorderImageRepeat(bool aAcceptsInherit);
// If ParseBorderImageSlice returns false, aConsumedTokens indicates
// whether or not any tokens were consumed (in other words, was the property
// in error or just not present). If ParseBorderImageSlice returns true
@@ -11074,21 +11078,21 @@ CSSParserImpl::ParseProperty(nsCSSProper
bool
CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
{
switch (aPropID) { // handle shorthand or multiple properties
case eCSSProperty_background:
return ParseBackground();
case eCSSProperty_background_repeat:
- return ParseBackgroundRepeat();
+ return ParseBackgroundRepeat(eCSSProperty_background_repeat);
case eCSSProperty_background_position:
- return ParseBackgroundPosition();
+ return ParseBackgroundPosition(eCSSProperty_background_position);
case eCSSProperty_background_size:
- return ParseBackgroundSize();
+ return ParseBackgroundSize(eCSSProperty_background_size);
case eCSSProperty_border:
return ParseBorderSide(kBorderTopIDs, true);
case eCSSProperty_border_color:
return ParseBorderColor();
case eCSSProperty_border_spacing:
return ParseBorderSpacing();
case eCSSProperty_border_style:
return ParseBorderStyle();
@@ -11523,22 +11527,23 @@ CSSParserImpl::ParseBackground()
for (const nsCSSProperty* subprops =
nsCSSProps::SubpropertyEntryFor(eCSSProperty_background);
*subprops != eCSSProperty_UNKNOWN; ++subprops) {
AppendValue(*subprops, color);
}
return true;
}
- nsCSSValue image, repeat, attachment, clip, origin, position, size;
- BackgroundParseState state(color, image.SetListValue(),
- repeat.SetPairListValue(),
- attachment.SetListValue(), clip.SetListValue(),
- origin.SetListValue(), position.SetListValue(),
- size.SetPairListValue());
+ nsCSSValue image, repeat, attachment, clip, origin, position, size, composite, mode;
+ BackgroundParseState state(color, image.SetListValue(),
+ repeat.SetPairListValue(),
+ attachment.SetListValue(), clip.SetListValue(),
+ origin.SetListValue(), position.SetListValue(),
+ size.SetPairListValue(), composite.SetListValue(),
+ mode.SetListValue());
for (;;) {
if (!ParseBackgroundItem(state)) {
return false;
}
// If we saw a color, this must be the last item.
if (color.GetUnit() != eCSSUnit_Null) {
break;
@@ -11829,17 +11834,17 @@ CSSParserImpl::ParseValueList(nsCSSPrope
item = item->mNext;
}
}
AppendValue(aPropID, value);
return true;
}
bool
-CSSParserImpl::ParseBackgroundRepeat()
+CSSParserImpl::ParseBackgroundRepeat(nsCSSProperty aPropID)
{
nsCSSValue value;
// 'initial', 'inherit' and 'unset' stand alone, no list permitted.
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
nsCSSValuePair valuePair;
if (!ParseBackgroundRepeatValues(valuePair)) {
return false;
}
@@ -11853,17 +11858,17 @@ CSSParserImpl::ParseBackgroundRepeat()
if (!ParseBackgroundRepeatValues(valuePair)) {
return false;
}
item->mNext = new nsCSSValuePairList;
item = item->mNext;
}
}
- AppendValue(eCSSProperty_background_repeat, value);
+ AppendValue(aPropID, value);
return true;
}
bool
CSSParserImpl::ParseBackgroundRepeatValues(nsCSSValuePair& aValue)
{
nsCSSValue& xValue = aValue.mXValue;
nsCSSValue& yValue = aValue.mYValue;
@@ -11882,17 +11887,17 @@ CSSParserImpl::ParseBackgroundRepeatValu
}
return false;
}
// This function is very similar to ParseScrollSnapCoordinate,
// ParseBackgroundList, and ParseBackgroundSize.
bool
-CSSParserImpl::ParseBackgroundPosition()
+CSSParserImpl::ParseBackgroundPosition(nsCSSProperty aPropID)
{
nsCSSValue value;
// 'initial', 'inherit' and 'unset' stand alone, no list permitted.
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
nsCSSValue itemValue;
if (!ParsePositionValue(itemValue)) {
return false;
}
@@ -11904,17 +11909,17 @@ CSSParserImpl::ParseBackgroundPosition()
}
if (!ParsePositionValue(itemValue)) {
return false;
}
item->mNext = new nsCSSValueList;
item = item->mNext;
}
}
- AppendValue(eCSSProperty_background_position, value);
+ AppendValue(aPropID, value);
return true;
}
/**
* BoxPositionMaskToCSSValue and ParseBoxPositionValues are used
* for parsing the CSS 2.1 background-position syntax (which has at
* most two values). (Compare to the css3-background syntax which
* takes up to four values.) Some current CSS specifications that
@@ -12200,17 +12205,17 @@ CSSParserImpl::ParsePositionValue(nsCSSV
}
return true;
}
// This function is very similar to ParseScrollSnapCoordinate,
// ParseBackgroundList, and ParseBackgroundPosition.
bool
-CSSParserImpl::ParseBackgroundSize()
+CSSParserImpl::ParseBackgroundSize(nsCSSProperty aPropID)
{
nsCSSValue value;
// 'initial', 'inherit' and 'unset' stand alone, no list permitted.
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
nsCSSValuePair valuePair;
if (!ParseBackgroundSizeValues(valuePair)) {
return false;
}
@@ -12223,17 +12228,17 @@ CSSParserImpl::ParseBackgroundSize()
}
if (!ParseBackgroundSizeValues(valuePair)) {
return false;
}
item->mNext = new nsCSSValuePairList;
item = item->mNext;
}
}
- AppendValue(eCSSProperty_background_size, value);
+ AppendValue(aPropID, value);
return true;
}
/**
* Parses two values that correspond to lengths for the background-size
* property. These can be one or two lengths (or the 'auto' keyword) or
* percentages corresponding to the element's dimensions or the single keywords
* 'contain' or 'cover'. 'initial', 'inherit' and 'unset' must be handled by
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1787,47 +1787,48 @@ nsComputedDOMStyle::DoGetFontVariantPosi
nsCSSProps::ValueToKeywordEnum(intValue,
nsCSSProps::kFontVariantPositionKTable));
}
return val;
}
CSSValue*
-nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember,
- uint32_t nsStyleBackground::* aCount,
+nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleImageLayers::Layer::* aMember,
+ uint32_t nsStyleImageLayers::* aCount,
+ const nsStyleImageLayers& aLayers,
const KTableEntry aTable[])
{
- const nsStyleBackground* bg = StyleBackground();
-
nsDOMCSSValueList *valueList = GetROCSSValueList(true);
- for (uint32_t i = 0, i_end = bg->*aCount; i < i_end; ++i) {
+ for (uint32_t i = 0, i_end = aLayers.*aCount; i < i_end; ++i) {
nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
valueList->AppendCSSValue(val);
- val->SetIdent(nsCSSProps::ValueToKeywordEnum(bg->mLayers[i].*aMember,
+ val->SetIdent(nsCSSProps::ValueToKeywordEnum(aLayers.mLayers[i].*aMember,
aTable));
}
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundAttachment()
{
- return GetBackgroundList(&nsStyleBackground::Layer::mAttachment,
- &nsStyleBackground::mAttachmentCount,
+ return GetBackgroundList(&nsStyleImageLayers::Layer::mAttachment,
+ &nsStyleImageLayers::mAttachmentCount,
+ StyleBackground()->mLayers,
nsCSSProps::kBackgroundAttachmentKTable);
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundClip()
{
- return GetBackgroundList(&nsStyleBackground::Layer::mClip,
- &nsStyleBackground::mClipCount,
+ return GetBackgroundList(&nsStyleImageLayers::Layer::mClip,
+ &nsStyleImageLayers::mClipCount,
+ StyleBackground()->mLayers,
nsCSSProps::kBackgroundOriginKTable);
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundColor()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
SetToRGBAColor(val, StyleBackground()->mBackgroundColor);
@@ -2120,62 +2121,64 @@ nsComputedDOMStyle::SetValueToStyleImage
CSSValue*
nsComputedDOMStyle::DoGetBackgroundImage()
{
const nsStyleBackground* bg = StyleBackground();
nsDOMCSSValueList *valueList = GetROCSSValueList(true);
- for (uint32_t i = 0, i_end = bg->mImageCount; i < i_end; ++i) {
+ for (uint32_t i = 0, i_end = bg->mLayers.mImageCount; i < i_end; ++i) {
nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
valueList->AppendCSSValue(val);
- const nsStyleImage& image = bg->mLayers[i].mImage;
+ const nsStyleImage& image = bg->mLayers.mLayers[i].mImage;
SetValueToStyleImage(image, val);
}
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundBlendMode()
{
- return GetBackgroundList(&nsStyleBackground::Layer::mBlendMode,
- &nsStyleBackground::mBlendModeCount,
+ return GetBackgroundList(&nsStyleImageLayers::Layer::mBlendMode,
+ &nsStyleImageLayers::mBlendModeCount,
+ StyleBackground()->mLayers,
nsCSSProps::kBlendModeKTable);
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundOrigin()
{
- return GetBackgroundList(&nsStyleBackground::Layer::mOrigin,
- &nsStyleBackground::mOriginCount,
+ return GetBackgroundList(&nsStyleImageLayers::Layer::mOrigin,
+ &nsStyleImageLayers::mOriginCount,
+ StyleBackground()->mLayers,
nsCSSProps::kBackgroundOriginKTable);
}
void
nsComputedDOMStyle::SetValueToPositionCoord(
- const nsStyleBackground::Position::PositionCoord& aCoord,
+ const nsStyleImageLayers::Position::PositionCoord& aCoord,
nsROCSSPrimitiveValue* aValue)
{
if (!aCoord.mHasPercent) {
MOZ_ASSERT(aCoord.mPercent == 0.0f,
"Shouldn't have mPercent!");
aValue->SetAppUnits(aCoord.mLength);
} else if (aCoord.mLength == 0) {
aValue->SetPercent(aCoord.mPercent);
} else {
SetValueToCalc(&aCoord, aValue);
}
}
void
nsComputedDOMStyle::SetValueToPosition(
- const nsStyleBackground::Position& aPosition,
+ const nsStyleImageLayers::Position& aPosition,
nsDOMCSSValueList* aValueList)
{
nsROCSSPrimitiveValue* valX = new nsROCSSPrimitiveValue;
aValueList->AppendCSSValue(valX);
SetValueToPositionCoord(aPosition.mXPosition, valX);
nsROCSSPrimitiveValue* valY = new nsROCSSPrimitiveValue;
aValueList->AppendCSSValue(valY);
@@ -2184,42 +2187,42 @@ nsComputedDOMStyle::SetValueToPosition(
CSSValue*
nsComputedDOMStyle::DoGetBackgroundPosition()
{
const nsStyleBackground* bg = StyleBackground();
nsDOMCSSValueList *valueList = GetROCSSValueList(true);
- for (uint32_t i = 0, i_end = bg->mPositionCount; i < i_end; ++i) {
+ for (uint32_t i = 0, i_end = bg->mLayers.mPositionCount; i < i_end; ++i) {
nsDOMCSSValueList *itemList = GetROCSSValueList(false);
valueList->AppendCSSValue(itemList);
- SetValueToPosition(bg->mLayers[i].mPosition, itemList);
+ SetValueToPosition(bg->mLayers.mLayers[i].mPosition, itemList);
}
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetBackgroundRepeat()
{
const nsStyleBackground* bg = StyleBackground();
nsDOMCSSValueList *valueList = GetROCSSValueList(true);
- for (uint32_t i = 0, i_end = bg->mRepeatCount; i < i_end; ++i) {
+ for (uint32_t i = 0, i_end = bg->mLayers.mRepeatCount; i < i_end; ++i) {
nsDOMCSSValueList *itemList = GetROCSSValueList(false);
valueList->AppendCSSValue(itemList);
nsROCSSPrimitiveValue *valX = new nsROCSSPrimitiveValue;
itemList->AppendCSSValue(valX);
- const uint8_t& xRepeat = bg->mLayers[i].mRepeat.mXRepeat;
- const uint8_t& yRepeat = bg->mLayers[i].mRepeat.mYRepeat;
+ const uint8_t& xRepeat = bg->mLayers.mLayers[i].mRepeat.mXRepeat;
+ const uint8_t& yRepeat = bg->mLayers.mLayers[i].mRepeat.mYRepeat;
bool hasContraction = true;
unsigned contraction;
if (xRepeat == yRepeat) {
contraction = xRepeat;
} else if (xRepeat == NS_STYLE_BG_REPEAT_REPEAT &&
yRepeat == NS_STYLE_BG_REPEAT_NO_REPEAT) {
contraction = NS_STYLE_BG_REPEAT_REPEAT_X;
@@ -2249,67 +2252,67 @@ nsComputedDOMStyle::DoGetBackgroundRepea
CSSValue*
nsComputedDOMStyle::DoGetBackgroundSize()
{
const nsStyleBackground* bg = StyleBackground();
nsDOMCSSValueList *valueList = GetROCSSValueList(true);
- for (uint32_t i = 0, i_end = bg->mSizeCount; i < i_end; ++i) {
- const nsStyleBackground::Size &size = bg->mLayers[i].mSize;
+ for (uint32_t i = 0, i_end = bg->mLayers.mSizeCount; i < i_end; ++i) {
+ const nsStyleImageLayers::Size &size = bg->mLayers.mLayers[i].mSize;
switch (size.mWidthType) {
- case nsStyleBackground::Size::eContain:
- case nsStyleBackground::Size::eCover: {
+ case nsStyleImageLayers::Size::eContain:
+ case nsStyleImageLayers::Size::eCover: {
MOZ_ASSERT(size.mWidthType == size.mHeightType,
"unsynced types");
- nsCSSKeyword keyword = size.mWidthType == nsStyleBackground::Size::eContain
+ nsCSSKeyword keyword = size.mWidthType == nsStyleImageLayers::Size::eContain
? eCSSKeyword_contain
: eCSSKeyword_cover;
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
valueList->AppendCSSValue(val);
val->SetIdent(keyword);
break;
}
default: {
nsDOMCSSValueList *itemList = GetROCSSValueList(false);
valueList->AppendCSSValue(itemList);
nsROCSSPrimitiveValue* valX = new nsROCSSPrimitiveValue;
itemList->AppendCSSValue(valX);
nsROCSSPrimitiveValue* valY = new nsROCSSPrimitiveValue;
itemList->AppendCSSValue(valY);
- if (size.mWidthType == nsStyleBackground::Size::eAuto) {
+ if (size.mWidthType == nsStyleImageLayers::Size::eAuto) {
valX->SetIdent(eCSSKeyword_auto);
} else {
MOZ_ASSERT(size.mWidthType ==
- nsStyleBackground::Size::eLengthPercentage,
+ nsStyleImageLayers::Size::eLengthPercentage,
"bad mWidthType");
if (!size.mWidth.mHasPercent &&
// negative values must have come from calc()
size.mWidth.mLength >= 0) {
MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
"Shouldn't have mPercent");
valX->SetAppUnits(size.mWidth.mLength);
} else if (size.mWidth.mLength == 0 &&
// negative values must have come from calc()
size.mWidth.mPercent >= 0.0f) {
valX->SetPercent(size.mWidth.mPercent);
} else {
SetValueToCalc(&size.mWidth, valX);
}
}
- if (size.mHeightType == nsStyleBackground::Size::eAuto) {
+ if (size.mHeightType == nsStyleImageLayers::Size::eAuto) {
valY->SetIdent(eCSSKeyword_auto);
} else {
MOZ_ASSERT(size.mHeightType ==
- nsStyleBackground::Size::eLengthPercentage,
+ nsStyleImageLayers::Size::eLengthPercentage,
"bad mHeightType");
if (!size.mHeight.mHasPercent &&
// negative values must have come from calc()
size.mHeight.mLength >= 0) {
MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
"Shouldn't have mPercent");
valY->SetAppUnits(size.mHeight.mLength);
} else if (size.mHeight.mLength == 0 &&
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -31,16 +31,17 @@ class Element;
struct nsComputedStyleMap;
class nsIFrame;
class nsIPresShell;
class nsDOMCSSValueList;
struct nsMargin;
class nsROCSSPrimitiveValue;
struct nsStyleBackground;
+struct nsStyleImageLayers;
class nsStyleCoord;
class nsStyleCorners;
struct nsStyleFilter;
class nsStyleGradient;
struct nsStyleImage;
class nsStyleSides;
struct nsTimingFunction;
@@ -183,18 +184,19 @@ private:
mozilla::dom::CSSValue* GetGridLine(const nsStyleGridLine& aGridLine);
bool GetLineHeightCoord(nscoord& aCoord);
mozilla::dom::CSSValue* GetCSSShadowArray(nsCSSShadowArray* aArray,
const nscolor& aDefaultColor,
bool aIsBoxShadow);
- mozilla::dom::CSSValue* GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember,
- uint32_t nsStyleBackground::* aCount,
+ mozilla::dom::CSSValue* GetBackgroundList(uint8_t nsStyleImageLayers::Layer::* aMember,
+ uint32_t nsStyleImageLayers::* aCount,
+ const nsStyleImageLayers& aLayers,
const KTableEntry aTable[]);
void GetCSSGradientString(const nsStyleGradient* aGradient,
nsAString& aString);
void GetImageRectString(nsIURI* aURI,
const nsStyleSides& aCropRect,
nsString& aString);
mozilla::dom::CSSValue* GetScrollSnapPoints(const nsStyleCoord& aCoord);
@@ -537,19 +539,19 @@ private:
nsDOMCSSValueList* GetROCSSValueList(bool aCommaDelimited);
/* Helper functions */
void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
void SetValueToStyleImage(const nsStyleImage& aStyleImage,
nsROCSSPrimitiveValue* aValue);
void SetValueToPositionCoord(
- const nsStyleBackground::Position::PositionCoord& aCoord,
+ const nsStyleImageLayers::Position::PositionCoord& aCoord,
nsROCSSPrimitiveValue* aValue);
- void SetValueToPosition(const nsStyleBackground::Position& aPosition,
+ void SetValueToPosition(const nsStyleImageLayers::Position& aPosition,
nsDOMCSSValueList* aValueList);
/**
* A method to get a percentage base for a percentage value. Returns true
* if a percentage base value was determined, false otherwise.
*/
typedef bool (nsComputedDOMStyle::*PercentageBaseGetter)(nscoord&);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -109,17 +109,17 @@ nsConditionalResetStyleData::GetConditio
NS_SET_IMAGE_REQUEST(method_, context_, requestgetter_(doc)) \
}
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
ComputePositionValue(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
- nsStyleBackground::Position& aComputedValue,
+ nsStyleImageLayers::Position& aComputedValue,
RuleNodeCacheConditions& aConditions);
/*
* For storage of an |nsRuleNode|'s children in a PLDHashTable.
*/
struct ChildrenHashEntry : public PLDHashEntryHdr {
// key is |mRuleNode->GetKey()|
@@ -5639,17 +5639,17 @@ nsRuleNode::ComputeDisplayData(void* aSt
break;
default: {
ComputePositionValue(aContext, snapDestination,
display->mScrollSnapDestination, conditions);
}
}
// scroll-snap-coordinate: none, inherit, initial
- typedef nsStyleBackground::Position Position;
+ typedef nsStyleImageLayers::Position Position;
const nsCSSValue& snapCoordinate = *aRuleData->ValueForScrollSnapCoordinate();
switch (snapCoordinate.GetUnit()) {
case eCSSUnit_Null:
break;
case eCSSUnit_Initial:
case eCSSUnit_Unset:
case eCSSUnit_None:
@@ -6356,51 +6356,51 @@ struct BackgroundItemComputer<nsCSSValue
RuleNodeCacheConditions& aConditions)
{
SetDiscrete(aSpecifiedValue->mValue, aComputedValue, aConditions,
SETDSC_ENUMERATED, uint8_t(0), 0, 0, 0, 0, 0);
}
};
template <>
-struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Repeat>
+struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Repeat>
{
static void ComputeValue(nsStyleContext* aStyleContext,
const nsCSSValuePairList* aSpecifiedValue,
- nsStyleBackground::Repeat& aComputedValue,
+ nsStyleImageLayers::Repeat& aComputedValue,
RuleNodeCacheConditions& aConditions)
{
NS_ASSERTION(aSpecifiedValue->mXValue.GetUnit() == eCSSUnit_Enumerated &&
(aSpecifiedValue->mYValue.GetUnit() == eCSSUnit_Enumerated ||
aSpecifiedValue->mYValue.GetUnit() == eCSSUnit_Null),
"Invalid unit");
-
+
bool hasContraction = true;
uint8_t value = aSpecifiedValue->mXValue.GetIntValue();
switch (value) {
case NS_STYLE_BG_REPEAT_REPEAT_X:
aComputedValue.mXRepeat = NS_STYLE_BG_REPEAT_REPEAT;
aComputedValue.mYRepeat = NS_STYLE_BG_REPEAT_NO_REPEAT;
break;
case NS_STYLE_BG_REPEAT_REPEAT_Y:
aComputedValue.mXRepeat = NS_STYLE_BG_REPEAT_NO_REPEAT;
aComputedValue.mYRepeat = NS_STYLE_BG_REPEAT_REPEAT;
break;
default:
aComputedValue.mXRepeat = value;
hasContraction = false;
break;
}
-
+
if (hasContraction) {
NS_ASSERTION(aSpecifiedValue->mYValue.GetUnit() == eCSSUnit_Null,
"Invalid unit.");
return;
}
-
+
switch (aSpecifiedValue->mYValue.GetUnit()) {
case eCSSUnit_Null:
aComputedValue.mYRepeat = aComputedValue.mXRepeat;
break;
case eCSSUnit_Enumerated:
value = aSpecifiedValue->mYValue.GetIntValue();
NS_ASSERTION(value == NS_STYLE_BG_REPEAT_NO_REPEAT ||
value == NS_STYLE_BG_REPEAT_REPEAT, "Unexpected value");
@@ -6425,17 +6425,17 @@ struct BackgroundItemComputer<nsCSSValue
aConditions);
}
};
/* Helper function for ComputePositionValue.
* This function computes a single PositionCoord from two nsCSSValue objects,
* which represent an edge and an offset from that edge.
*/
-typedef nsStyleBackground::Position::PositionCoord PositionCoord;
+typedef nsStyleImageLayers::Position::PositionCoord PositionCoord;
static void
ComputePositionCoord(nsStyleContext* aStyleContext,
const nsCSSValue& aEdge,
const nsCSSValue& aOffset,
PositionCoord* aResult,
RuleNodeCacheConditions& aConditions)
{
if (eCSSUnit_Percent == aOffset.GetUnit()) {
@@ -6480,17 +6480,17 @@ ComputePositionCoord(nsStyleContext* aSt
}
}
/* Helper function to convert a CSS <position> specified value into its
* computed-style form. */
static void
ComputePositionValue(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
- nsStyleBackground::Position& aComputedValue,
+ nsStyleImageLayers::Position& aComputedValue,
RuleNodeCacheConditions& aConditions)
{
NS_ASSERTION(aValue.GetUnit() == eCSSUnit_Array,
"unexpected unit for CSS <position> value");
RefPtr<nsCSSValue::Array> positionArray = aValue.GetArrayValue();
const nsCSSValue &xEdge = positionArray->Item(0);
const nsCSSValue &xOffset = positionArray->Item(1);
@@ -6510,64 +6510,64 @@ ComputePositionValue(nsStyleContext* aSt
aConditions);
ComputePositionCoord(aStyleContext, yEdge, yOffset,
&aComputedValue.mYPosition,
aConditions);
}
template <>
-struct BackgroundItemComputer<nsCSSValueList, nsStyleBackground::Position>
+struct BackgroundItemComputer<nsCSSValueList, nsStyleImageLayers::Position>
{
static void ComputeValue(nsStyleContext* aStyleContext,
const nsCSSValueList* aSpecifiedValue,
- nsStyleBackground::Position& aComputedValue,
+ nsStyleImageLayers::Position& aComputedValue,
RuleNodeCacheConditions& aConditions)
{
ComputePositionValue(aStyleContext, aSpecifiedValue->mValue,
aComputedValue, aConditions);
}
};
struct BackgroundSizeAxis {
nsCSSValue nsCSSValuePairList::* specified;
- nsStyleBackground::Size::Dimension nsStyleBackground::Size::* result;
- uint8_t nsStyleBackground::Size::* type;
+ nsStyleImageLayers::Size::Dimension nsStyleImageLayers::Size::* result;
+ uint8_t nsStyleImageLayers::Size::* type;
};
static const BackgroundSizeAxis gBGSizeAxes[] = {
{ &nsCSSValuePairList::mXValue,
- &nsStyleBackground::Size::mWidth,
- &nsStyleBackground::Size::mWidthType },
+ &nsStyleImageLayers::Size::mWidth,
+ &nsStyleImageLayers::Size::mWidthType },
{ &nsCSSValuePairList::mYValue,
- &nsStyleBackground::Size::mHeight,
- &nsStyleBackground::Size::mHeightType }
+ &nsStyleImageLayers::Size::mHeight,
+ &nsStyleImageLayers::Size::mHeightType }
};
template <>
-struct BackgroundItemComputer<nsCSSValuePairList, nsStyleBackground::Size>
+struct BackgroundItemComputer<nsCSSValuePairList, nsStyleImageLayers::Size>
{
static void ComputeValue(nsStyleContext* aStyleContext,
const nsCSSValuePairList* aSpecifiedValue,
- nsStyleBackground::Size& aComputedValue,
+ nsStyleImageLayers::Size& aComputedValue,
RuleNodeCacheConditions& aConditions)
{
- nsStyleBackground::Size &size = aComputedValue;
+ nsStyleImageLayers::Size &size = aComputedValue;
for (const BackgroundSizeAxis *axis = gBGSizeAxes,
*axis_end = ArrayEnd(gBGSizeAxes);
axis < axis_end; ++axis) {
const nsCSSValue &specified = aSpecifiedValue->*(axis->specified);
if (eCSSUnit_Auto == specified.GetUnit()) {
- size.*(axis->type) = nsStyleBackground::Size::eAuto;
+ size.*(axis->type) = nsStyleImageLayers::Size::eAuto;
}
else if (eCSSUnit_Enumerated == specified.GetUnit()) {
- static_assert(nsStyleBackground::Size::eContain ==
+ static_assert(nsStyleImageLayers::Size::eContain ==
NS_STYLE_BG_SIZE_CONTAIN &&
- nsStyleBackground::Size::eCover ==
+ nsStyleImageLayers::Size::eCover ==
NS_STYLE_BG_SIZE_COVER,
"background size constants out of sync");
MOZ_ASSERT(specified.GetIntValue() == NS_STYLE_BG_SIZE_CONTAIN ||
specified.GetIntValue() == NS_STYLE_BG_SIZE_COVER,
"invalid enumerated value for size coordinate");
size.*(axis->type) = specified.GetIntValue();
}
else if (eCSSUnit_Null == specified.GetUnit()) {
@@ -6589,56 +6589,56 @@ struct BackgroundItemComputer<nsCSSValue
}
#endif
size.*(axis->type) = size.mWidthType;
}
else if (eCSSUnit_Percent == specified.GetUnit()) {
(size.*(axis->result)).mLength = 0;
(size.*(axis->result)).mPercent = specified.GetPercentValue();
(size.*(axis->result)).mHasPercent = true;
- size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage;
+ size.*(axis->type) = nsStyleImageLayers::Size::eLengthPercentage;
}
else if (specified.IsLengthUnit()) {
(size.*(axis->result)).mLength =
CalcLength(specified, aStyleContext, aStyleContext->PresContext(),
aConditions);
(size.*(axis->result)).mPercent = 0.0f;
(size.*(axis->result)).mHasPercent = false;
- size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage;
+ size.*(axis->type) = nsStyleImageLayers::Size::eLengthPercentage;
} else {
MOZ_ASSERT(specified.IsCalcUnit(), "unexpected unit");
LengthPercentPairCalcOps ops(aStyleContext,
aStyleContext->PresContext(),
aConditions);
nsRuleNode::ComputedCalc vals = ComputeCalc(specified, ops);
(size.*(axis->result)).mLength = vals.mLength;
(size.*(axis->result)).mPercent = vals.mPercent;
(size.*(axis->result)).mHasPercent = ops.mHasPercent;
- size.*(axis->type) = nsStyleBackground::Size::eLengthPercentage;
- }
- }
-
- MOZ_ASSERT(size.mWidthType < nsStyleBackground::Size::eDimensionType_COUNT,
+ size.*(axis->type) = nsStyleImageLayers::Size::eLengthPercentage;
+ }
+ }
+
+ MOZ_ASSERT(size.mWidthType < nsStyleImageLayers::Size::eDimensionType_COUNT,
"bad width type");
- MOZ_ASSERT(size.mHeightType < nsStyleBackground::Size::eDimensionType_COUNT,
+ MOZ_ASSERT(size.mHeightType < nsStyleImageLayers::Size::eDimensionType_COUNT,
"bad height type");
- MOZ_ASSERT((size.mWidthType != nsStyleBackground::Size::eContain &&
- size.mWidthType != nsStyleBackground::Size::eCover) ||
+ MOZ_ASSERT((size.mWidthType != nsStyleImageLayers::Size::eContain &&
+ size.mWidthType != nsStyleImageLayers::Size::eCover) ||
size.mWidthType == size.mHeightType,
"contain/cover apply to both dimensions or to neither");
}
};
template <class ComputedValueItem>
static void
SetBackgroundList(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
- nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
- const nsAutoTArray<nsStyleBackground::Layer, 1> &aParentLayers,
- ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
+ nsAutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
+ const nsAutoTArray<nsStyleImageLayers::Layer, 1> &aParentLayers,
+ ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation,
ComputedValueItem aInitialValue,
uint32_t aParentItemCount,
uint32_t& aItemCount,
uint32_t& aMaxItemCount,
bool& aRebuild,
RuleNodeCacheConditions& aConditions)
{
switch (aValue.GetUnit()) {
@@ -6691,20 +6691,20 @@ SetBackgroundList(nsStyleContext* aStyle
if (aItemCount > aMaxItemCount)
aMaxItemCount = aItemCount;
}
template <class ComputedValueItem>
static void
SetBackgroundPairList(nsStyleContext* aStyleContext,
const nsCSSValue& aValue,
- nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
- const nsAutoTArray<nsStyleBackground::Layer, 1>
+ nsAutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
+ const nsAutoTArray<nsStyleImageLayers::Layer, 1>
&aParentLayers,
- ComputedValueItem nsStyleBackground::Layer::*
+ ComputedValueItem nsStyleImageLayers::Layer::*
aResultLocation,
ComputedValueItem aInitialValue,
uint32_t aParentItemCount,
uint32_t& aItemCount,
uint32_t& aMaxItemCount,
bool& aRebuild,
RuleNodeCacheConditions& aConditions)
{
@@ -6758,18 +6758,18 @@ SetBackgroundPairList(nsStyleContext* aS
}
if (aItemCount > aMaxItemCount)
aMaxItemCount = aItemCount;
}
template <class ComputedValueItem>
static void
-FillBackgroundList(nsAutoTArray< nsStyleBackground::Layer, 1> &aLayers,
- ComputedValueItem nsStyleBackground::Layer::* aResultLocation,
+FillBackgroundList(nsAutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
+ ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation,
uint32_t aItemCount, uint32_t aFillCount)
{
NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length");
for (uint32_t sourceLayer = 0, destLayer = aItemCount;
destLayer < aFillCount;
++sourceLayer, ++destLayer) {
aLayers[destLayer].*aResultLocation =
aLayers[sourceLayer].*aResultLocation;
@@ -6799,110 +6799,109 @@ nsRuleNode::ComputeBackgroundData(void*
}
uint32_t maxItemCount = 1;
bool rebuild = false;
// background-image: url (stored as image), none, inherit [list]
nsStyleImage initialImage;
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundImage(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mImage,
- initialImage, parentBG->mImageCount, bg->mImageCount,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mImage,
+ initialImage, parentBG->mLayers.mImageCount, bg->mLayers.mImageCount,
maxItemCount, rebuild, conditions);
// background-repeat: enum, inherit, initial [pair list]
- nsStyleBackground::Repeat initialRepeat;
+ nsStyleImageLayers::Repeat initialRepeat;
initialRepeat.SetInitialValues();
SetBackgroundPairList(aContext, *aRuleData->ValueForBackgroundRepeat(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mRepeat,
- initialRepeat, parentBG->mRepeatCount,
- bg->mRepeatCount, maxItemCount, rebuild,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mRepeat,
+ initialRepeat, parentBG->mLayers.mRepeatCount,
+ bg->mLayers.mRepeatCount, maxItemCount, rebuild,
conditions);
// background-attachment: enum, inherit, initial [list]
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundAttachment(),
- bg->mLayers, parentBG->mLayers,
- &nsStyleBackground::Layer::mAttachment,
+ bg->mLayers.mLayers, parentBG->mLayers.mLayers,
+ &nsStyleImageLayers::Layer::mAttachment,
uint8_t(NS_STYLE_BG_ATTACHMENT_SCROLL),
- parentBG->mAttachmentCount,
- bg->mAttachmentCount, maxItemCount, rebuild,
+ parentBG->mLayers.mAttachmentCount,
+ bg->mLayers.mAttachmentCount, maxItemCount, rebuild,
conditions);
// background-clip: enum, inherit, initial [list]
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundClip(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mClip,
- uint8_t(NS_STYLE_BG_CLIP_BORDER), parentBG->mClipCount,
- bg->mClipCount, maxItemCount, rebuild, conditions);
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mClip,
+ uint8_t(NS_STYLE_BG_CLIP_BORDER), parentBG->mLayers.mClipCount,
+ bg->mLayers.mClipCount, maxItemCount, rebuild, conditions);
// background-blend-mode: enum, inherit, initial [list]
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundBlendMode(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mBlendMode,
- uint8_t(NS_STYLE_BLEND_NORMAL), parentBG->mBlendModeCount,
- bg->mBlendModeCount, maxItemCount, rebuild,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mBlendMode,
+ uint8_t(NS_STYLE_BLEND_NORMAL), parentBG->mLayers.mBlendModeCount,
+ bg->mLayers.mBlendModeCount, maxItemCount, rebuild,
conditions);
// background-origin: enum, inherit, initial [list]
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundOrigin(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mOrigin,
- uint8_t(NS_STYLE_BG_ORIGIN_PADDING), parentBG->mOriginCount,
- bg->mOriginCount, maxItemCount, rebuild,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mOrigin,
+ uint8_t(NS_STYLE_BG_ORIGIN_PADDING), parentBG->mLayers.mOriginCount,
+ bg->mLayers.mOriginCount, maxItemCount, rebuild,
conditions);
// background-position: enum, length, percent (flags), inherit [pair list]
- nsStyleBackground::Position initialPosition;
+ nsStyleImageLayers::Position initialPosition;
initialPosition.SetInitialPercentValues(0.0f);
SetBackgroundList(aContext, *aRuleData->ValueForBackgroundPosition(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mPosition,
- initialPosition, parentBG->mPositionCount,
- bg->mPositionCount, maxItemCount, rebuild,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mPosition,
+ initialPosition, parentBG->mLayers.mPositionCount,
+ bg->mLayers.mPositionCount, maxItemCount, rebuild,
conditions);
// background-size: enum, length, auto, inherit, initial [pair list]
- nsStyleBackground::Size initialSize;
+ nsStyleImageLayers::Size initialSize;
initialSize.SetInitialValues();
SetBackgroundPairList(aContext, *aRuleData->ValueForBackgroundSize(),
- bg->mLayers,
- parentBG->mLayers, &nsStyleBackground::Layer::mSize,
- initialSize, parentBG->mSizeCount,
- bg->mSizeCount, maxItemCount, rebuild,
+ bg->mLayers.mLayers,
+ parentBG->mLayers.mLayers, &nsStyleImageLayers::Layer::mSize,
+ initialSize, parentBG->mLayers.mSizeCount,
+ bg->mLayers.mSizeCount, maxItemCount, rebuild,
conditions);
if (rebuild) {
// Delete any extra items. We need to keep layers in which any
// property was specified.
- bg->mLayers.TruncateLength(maxItemCount);
-
- uint32_t fillCount = bg->mImageCount;
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mImage,
- bg->mImageCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mRepeat,
- bg->mRepeatCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mAttachment,
- bg->mAttachmentCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mClip,
- bg->mClipCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mBlendMode,
- bg->mBlendModeCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mOrigin,
- bg->mOriginCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mPosition,
- bg->mPositionCount, fillCount);
- FillBackgroundList(bg->mLayers, &nsStyleBackground::Layer::mSize,
- bg->mSizeCount, fillCount);
+ bg->mLayers.mLayers.TruncateLength(maxItemCount);
+
+ uint32_t fillCount = bg->mLayers.mImageCount;
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mImage,
+ bg->mLayers.mImageCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mRepeat,
+ bg->mLayers.mRepeatCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mAttachment,
+ bg->mLayers.mAttachmentCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mClip,
+ bg->mLayers.mClipCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mBlendMode,
+ bg->mLayers.mBlendModeCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mOrigin,
+ bg->mLayers.mOriginCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mPosition,
+ bg->mLayers.mPositionCount, fillCount);
+ FillBackgroundList(bg->mLayers.mLayers, &nsStyleImageLayers::Layer::mSize,
+ bg->mLayers.mSizeCount, fillCount);
}
// Now that the dust has settled, register the images with the document
- for (uint32_t i = 0; i < bg->mImageCount; ++i)
- bg->mLayers[i].TrackImages(aContext->PresContext());
+ bg->mLayers.TrackImages(aContext->PresContext());
COMPUTE_END_RESET(Background, bg)
}
const void*
nsRuleNode::ComputeMarginData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1269,31 +1269,31 @@ nsStyleFilter::SetDropShadow(nsCSSShadow
mDropShadow = aDropShadow;
mDropShadow->AddRef();
mType = NS_STYLE_FILTER_DROP_SHADOW;
}
// --------------------
// nsStyleSVGReset
//
-nsStyleSVGReset::nsStyleSVGReset()
+nsStyleSVGReset::nsStyleSVGReset()
{
MOZ_COUNT_CTOR(nsStyleSVGReset);
mStopColor = NS_RGB(0,0,0);
mFloodColor = NS_RGB(0,0,0);
mLightingColor = NS_RGB(255,255,255);
mMask = nullptr;
mStopOpacity = 1.0f;
mFloodOpacity = 1.0f;
mDominantBaseline = NS_STYLE_DOMINANT_BASELINE_AUTO;
mVectorEffect = NS_STYLE_VECTOR_EFFECT_NONE;
mMaskType = NS_STYLE_MASK_TYPE_LUMINANCE;
}
-nsStyleSVGReset::~nsStyleSVGReset()
+nsStyleSVGReset::~nsStyleSVGReset()
{
MOZ_COUNT_DTOR(nsStyleSVGReset);
}
nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
{
MOZ_COUNT_CTOR(nsStyleSVGReset);
mStopColor = aSource.mStopColor;
@@ -2270,170 +2270,83 @@ nsStyleImage::operator==(const nsStyleIm
if (mType == eStyleImageType_Element)
return NS_strcmp(mElementId, aOther.mElementId) == 0;
return true;
}
// --------------------
-// nsStyleBackground
+// nsStyleImageLayers
//
-nsStyleBackground::nsStyleBackground()
+nsStyleImageLayers::nsStyleImageLayers()
: mAttachmentCount(1)
, mClipCount(1)
, mOriginCount(1)
, mRepeatCount(1)
, mPositionCount(1)
, mImageCount(1)
, mSizeCount(1)
, mBlendModeCount(1)
- , mBackgroundColor(NS_RGBA(0, 0, 0, 0))
{
- MOZ_COUNT_CTOR(nsStyleBackground);
- Layer *onlyLayer = mLayers.AppendElement();
- NS_ASSERTION(onlyLayer, "auto array must have room for 1 element");
- onlyLayer->SetInitialValues();
+ mLayers.AppendElement();
+ NS_ASSERTION(mLayers.Length() == 1, "auto array must have room for 1 element");
}
-nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
+nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers &aSource)
: mAttachmentCount(aSource.mAttachmentCount)
, mClipCount(aSource.mClipCount)
, mOriginCount(aSource.mOriginCount)
, mRepeatCount(aSource.mRepeatCount)
, mPositionCount(aSource.mPositionCount)
, mImageCount(aSource.mImageCount)
, mSizeCount(aSource.mSizeCount)
, mBlendModeCount(aSource.mBlendModeCount)
, mLayers(aSource.mLayers) // deep copy
- , mBackgroundColor(aSource.mBackgroundColor)
{
- MOZ_COUNT_CTOR(nsStyleBackground);
// If the deep copy of mLayers failed, truncate the counts.
uint32_t count = mLayers.Length();
if (count != aSource.mLayers.Length()) {
NS_WARNING("truncating counts due to out-of-memory");
mAttachmentCount = std::max(mAttachmentCount, count);
mClipCount = std::max(mClipCount, count);
mOriginCount = std::max(mOriginCount, count);
mRepeatCount = std::max(mRepeatCount, count);
mPositionCount = std::max(mPositionCount, count);
mImageCount = std::max(mImageCount, count);
mSizeCount = std::max(mSizeCount, count);
- mBlendModeCount = std::max(mSizeCount, count);
+ mBlendModeCount = std::max(mBlendModeCount, count);
}
}
-nsStyleBackground::~nsStyleBackground()
-{
- MOZ_COUNT_DTOR(nsStyleBackground);
-}
-
void
-nsStyleBackground::Destroy(nsPresContext* aContext)
-{
- // Untrack all the images stored in our layers
- for (uint32_t i = 0; i < mImageCount; ++i)
- mLayers[i].UntrackImages(aContext);
-
- this->~nsStyleBackground();
- aContext->PresShell()->
- FreeByObjectID(eArenaObjectID_nsStyleBackground, this);
-}
-
-nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
-{
- const nsStyleBackground* moreLayers =
- mImageCount > aOther.mImageCount ? this : &aOther;
- const nsStyleBackground* lessLayers =
- mImageCount > aOther.mImageCount ? &aOther : this;
-
- nsChangeHint hint = nsChangeHint(0);
-
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, moreLayers) {
- if (i < lessLayers->mImageCount) {
- nsChangeHint layerDifference = moreLayers->mLayers[i].CalcDifference(lessLayers->mLayers[i]);
- hint |= layerDifference;
- if (layerDifference &&
- ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
- (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))) {
- hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
- }
- } else {
- hint |= nsChangeHint_RepaintFrame;
- if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) {
- hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
- }
- }
- }
-
- if (mBackgroundColor != aOther.mBackgroundColor) {
- hint |= nsChangeHint_RepaintFrame;
- }
-
- if (hint) {
- return hint;
- }
-
- if (mAttachmentCount != aOther.mAttachmentCount ||
- mClipCount != aOther.mClipCount ||
- mOriginCount != aOther.mOriginCount ||
- mRepeatCount != aOther.mRepeatCount ||
- mPositionCount != aOther.mPositionCount ||
- mSizeCount != aOther.mSizeCount) {
- return nsChangeHint_NeutralChange;
- }
-
- return NS_STYLE_HINT_NONE;
-}
-
-bool nsStyleBackground::HasFixedBackground() const
-{
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
- const Layer &layer = mLayers[i];
- if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
- !layer.mImage.IsEmpty()) {
- return true;
- }
- }
- return false;
-}
-
-bool nsStyleBackground::IsTransparent() const
-{
- return BottomLayer().mImage.IsEmpty() &&
- mImageCount == 1 &&
- NS_GET_A(mBackgroundColor) == 0;
-}
-
-void
-nsStyleBackground::Position::SetInitialPercentValues(float aPercentVal)
+nsStyleImageLayers::Position::SetInitialPercentValues(float aPercentVal)
{
mXPosition.mPercent = aPercentVal;
mXPosition.mLength = 0;
mXPosition.mHasPercent = true;
mYPosition.mPercent = aPercentVal;
mYPosition.mLength = 0;
mYPosition.mHasPercent = true;
}
void
-nsStyleBackground::Position::SetInitialZeroValues()
+nsStyleImageLayers::Position::SetInitialZeroValues()
{
mXPosition.mPercent = 0;
mXPosition.mLength = 0;
mXPosition.mHasPercent = false;
mYPosition.mPercent = 0;
mYPosition.mLength = 0;
mYPosition.mHasPercent = false;
}
bool
-nsStyleBackground::Size::DependsOnPositioningAreaSize(const nsStyleImage& aImage) const
+nsStyleImageLayers::Size::DependsOnPositioningAreaSize(const nsStyleImage& aImage) const
{
MOZ_ASSERT(aImage.GetType() != eStyleImageType_Null,
"caller should have handled this");
// If either dimension contains a non-zero percentage, rendering for that
// dimension straightforwardly depends on frame size.
if ((mWidthType == eLengthPercentage && mWidth.mPercent != 0.0f) ||
(mHeightType == eLengthPercentage && mHeight.mPercent != 0.0f)) {
@@ -2502,23 +2415,23 @@ nsStyleBackground::Size::DependsOnPositi
NS_NOTREACHED("missed an enum value");
}
// Passed the gauntlet: no dependency.
return false;
}
void
-nsStyleBackground::Size::SetInitialValues()
+nsStyleImageLayers::Size::SetInitialValues()
{
mWidthType = mHeightType = eAuto;
}
bool
-nsStyleBackground::Size::operator==(const Size& aOther) const
+nsStyleImageLayers::Size::operator==(const Size& aOther) const
{
MOZ_ASSERT(mWidthType < eDimensionType_COUNT,
"bad mWidthType for this");
MOZ_ASSERT(mHeightType < eDimensionType_COUNT,
"bad mHeightType for this");
MOZ_ASSERT(aOther.mWidthType < eDimensionType_COUNT,
"bad mWidthType for aOther");
MOZ_ASSERT(aOther.mHeightType < eDimensionType_COUNT,
@@ -2526,70 +2439,65 @@ nsStyleBackground::Size::operator==(cons
return mWidthType == aOther.mWidthType &&
mHeightType == aOther.mHeightType &&
(mWidthType != eLengthPercentage || mWidth == aOther.mWidth) &&
(mHeightType != eLengthPercentage || mHeight == aOther.mHeight);
}
void
-nsStyleBackground::Repeat::SetInitialValues()
+nsStyleImageLayers::Repeat::SetInitialValues()
{
mXRepeat = NS_STYLE_BG_REPEAT_REPEAT;
mYRepeat = NS_STYLE_BG_REPEAT_REPEAT;
}
-nsStyleBackground::Layer::Layer()
+nsStyleImageLayers::Layer::Layer()
+: mClip(NS_STYLE_BG_CLIP_BORDER),
+ mOrigin(NS_STYLE_BG_ORIGIN_PADDING),
+ mAttachment(NS_STYLE_BG_ATTACHMENT_SCROLL),
+ mBlendMode(NS_STYLE_BLEND_NORMAL)
{
-}
-
-nsStyleBackground::Layer::~Layer()
-{
+ mPosition.SetInitialPercentValues(0.0f); // Initial value is "0% 0%"
+ mImage.SetNull();
+ mRepeat.SetInitialValues();
+ mSize.SetInitialValues();
}
-void
-nsStyleBackground::Layer::SetInitialValues()
+nsStyleImageLayers::Layer::~Layer()
{
- mAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
- mClip = NS_STYLE_BG_CLIP_BORDER;
- mOrigin = NS_STYLE_BG_ORIGIN_PADDING;
- mRepeat.SetInitialValues();
- mBlendMode = NS_STYLE_BLEND_NORMAL;
- mPosition.SetInitialPercentValues(0.0f); // Initial value is "0% 0%"
- mSize.SetInitialValues();
- mImage.SetNull();
}
bool
-nsStyleBackground::Layer::RenderingMightDependOnPositioningAreaSizeChange() const
+nsStyleImageLayers::Layer::RenderingMightDependOnPositioningAreaSizeChange() const
{
// Do we even have an image?
if (mImage.IsEmpty()) {
return false;
}
return mPosition.DependsOnPositioningAreaSize() ||
mSize.DependsOnPositioningAreaSize(mImage);
}
bool
-nsStyleBackground::Layer::operator==(const Layer& aOther) const
+nsStyleImageLayers::Layer::operator==(const Layer& aOther) const
{
return mAttachment == aOther.mAttachment &&
mClip == aOther.mClip &&
mOrigin == aOther.mOrigin &&
mRepeat == aOther.mRepeat &&
mBlendMode == aOther.mBlendMode &&
mPosition == aOther.mPosition &&
mSize == aOther.mSize &&
mImage == aOther.mImage;
}
nsChangeHint
-nsStyleBackground::Layer::CalcDifference(const Layer& aOther) const
+nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aOther) const
{
nsChangeHint hint = nsChangeHint(0);
if (mAttachment != aOther.mAttachment ||
mClip != aOther.mClip ||
mOrigin != aOther.mOrigin ||
mRepeat != aOther.mRepeat ||
mBlendMode != aOther.mBlendMode ||
mSize != aOther.mSize ||
@@ -2598,16 +2506,119 @@ nsStyleBackground::Layer::CalcDifference
}
if (mPosition != aOther.mPosition) {
hint |= nsChangeHint_SchedulePaint;
}
return hint;
}
// --------------------
+// nsStyleBackground
+//
+
+nsStyleBackground::nsStyleBackground()
+ : mBackgroundColor(NS_RGBA(0, 0, 0, 0))
+{
+ MOZ_COUNT_CTOR(nsStyleBackground);
+}
+
+nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
+ : mLayers(aSource.mLayers)
+ , mBackgroundColor(aSource.mBackgroundColor)
+{
+ MOZ_COUNT_CTOR(nsStyleBackground);
+
+}
+
+nsStyleBackground::~nsStyleBackground()
+{
+ MOZ_COUNT_DTOR(nsStyleBackground);
+}
+
+void
+nsStyleBackground::Destroy(nsPresContext* aContext)
+{
+ // Untrack all the images stored in our layers
+ mLayers.UntrackImages(aContext);
+
+ this->~nsStyleBackground();
+ aContext->PresShell()->
+ FreeByObjectID(eArenaObjectID_nsStyleBackground, this);
+}
+
+nsChangeHint nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
+{
+ const nsStyleImageLayers& moreLayers =
+ mLayers.mImageCount > aOther.mLayers.mImageCount ?
+ this->mLayers : aOther.mLayers;
+ const nsStyleImageLayers& lessLayers =
+ mLayers.mImageCount > aOther.mLayers.mImageCount ?
+ aOther.mLayers : this->mLayers;
+
+ nsChangeHint hint = nsChangeHint(0);
+
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, moreLayers) {
+ if (i < lessLayers.mImageCount) {
+ nsChangeHint layerDifference = moreLayers.mLayers[i].
+ CalcDifference(lessLayers.mLayers[i]);
+ hint |= layerDifference;
+ if (layerDifference &&
+ ((moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
+ (lessLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element))) {
+ hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
+ }
+ } else {
+ hint |= nsChangeHint_RepaintFrame;
+ if (moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) {
+ hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
+ }
+ }
+ }
+
+ if (mBackgroundColor != aOther.mBackgroundColor) {
+ hint |= nsChangeHint_RepaintFrame;
+ }
+
+ if (hint) {
+ return hint;
+ }
+
+ if (mLayers.mAttachmentCount != aOther.mLayers.mAttachmentCount ||
+ mLayers.mClipCount != aOther.mLayers.mClipCount ||
+ mLayers.mOriginCount != aOther.mLayers.mOriginCount ||
+ mLayers.mRepeatCount != aOther.mLayers.mRepeatCount ||
+ mLayers.mPositionCount != aOther.mLayers.mPositionCount ||
+ mLayers.mSizeCount != aOther.mLayers.mSizeCount) {
+ return nsChangeHint_NeutralChange;
+ }
+
+
+ return NS_STYLE_HINT_NONE;
+}
+
+bool nsStyleBackground::HasFixedBackground() const
+{
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, mLayers) {
+ const nsStyleImageLayers::Layer &layer = mLayers.mLayers[i];
+ if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
+ !layer.mImage.IsEmpty()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool nsStyleBackground::IsTransparent() const
+{
+ return BottomLayer().mImage.IsEmpty() &&
+ mLayers.mImageCount == 1 &&
+ NS_GET_A(mBackgroundColor) == 0;
+}
+
+// --------------------
// nsStyleDisplay
//
void nsTimingFunction::AssignFromKeyword(int32_t aTimingFunctionType)
{
switch (aTimingFunctionType) {
case NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START:
mType = Type::StepStart;
mStepSyntax = StepSyntax::Keyword;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -388,39 +388,19 @@ struct nsStyleColor {
FreeByObjectID(mozilla::eArenaObjectID_nsStyleColor, this);
}
// Don't add ANY members to this struct! We can achieve caching in the rule
// tree (rather than the style tree) by letting color stay by itself! -dwh
nscolor mColor; // [inherited]
};
-struct nsStyleBackground {
- nsStyleBackground();
- nsStyleBackground(const nsStyleBackground& aOther);
- ~nsStyleBackground();
-
- void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
- return aContext->PresShell()->
- AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
- }
- void Destroy(nsPresContext* aContext);
-
- nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
- static nsChangeHint MaxDifference() {
- return nsChangeHint_UpdateEffects |
- nsChangeHint_RepaintFrame |
- nsChangeHint_SchedulePaint |
- nsChangeHint_NeutralChange;
- }
- static nsChangeHint DifferenceAlwaysHandledForDescendants() {
- // CalcDifference never returns the reflow hints that are sometimes
- // handled for descendants at all.
- return nsChangeHint(0);
- }
+struct nsStyleImageLayers {
+ nsStyleImageLayers();
+ nsStyleImageLayers(const nsStyleImageLayers &aSource);
struct Position;
friend struct Position;
struct Position {
typedef nsStyleCoord::CalcValue PositionCoord;
PositionCoord mXPosition, mYPosition;
// Initialize nothing
@@ -525,42 +505,50 @@ struct nsStyleBackground {
bool operator!=(const Repeat& aOther) const {
return !(*this == aOther);
}
};
struct Layer;
friend struct Layer;
struct Layer {
- uint8_t mAttachment; // [reset] See nsStyleConsts.h
- uint8_t mClip; // [reset] See nsStyleConsts.h
- uint8_t mOrigin; // [reset] See nsStyleConsts.h
- uint8_t mBlendMode; // [reset] See nsStyleConsts.h
- Repeat mRepeat; // [reset] See nsStyleConsts.h
- Position mPosition; // [reset]
- nsStyleImage mImage; // [reset]
- Size mSize; // [reset]
+ nsStyleImage mImage; // [reset]
+ Position mPosition; // [reset] See nsStyleConsts.h
+ Size mSize; // [reset]
+ uint8_t mClip; // [reset] See nsStyleConsts.h
+ uint8_t mOrigin; // [reset] See nsStyleConsts.h
+ uint8_t mAttachment; // [reset] See nsStyleConsts.h
+ // background-only property
+ // This property is used for background layer
+ // only. For a mask layer, it should always
+ // be the initial value, which is
+ // NS_STYLE_BG_ATTACHMENT_SCROLL.
+ uint8_t mBlendMode; // [reset] See nsStyleConsts.h
+ // background-only property
+ // This property is used for background layer
+ // only. For a mask layer, it should always
+ // be the initial value, which is
+ // NS_STYLE_BLEND_NORMAL.
+ Repeat mRepeat; // [reset] See nsStyleConsts.h
// Initializes only mImage
Layer();
~Layer();
// Register/unregister images with the document. We do this only
// after the dust has settled in ComputeBackgroundData.
void TrackImages(nsPresContext* aContext) {
if (mImage.GetType() == eStyleImageType_Image)
mImage.TrackImage(aContext);
}
void UntrackImages(nsPresContext* aContext) {
if (mImage.GetType() == eStyleImageType_Image)
mImage.UntrackImage(aContext);
}
- void SetInitialValues();
-
// True if the rendering of this layer might change when the size
// of the background positioning area changes. This is true for any
// non-solid-color background whose position or size depends on
// the size of the positioning area. It's also true for SVG images
// whose root <svg> node has a viewBox.
bool RenderingMightDependOnPositioningAreaSizeChange() const;
// Compute the change hint required by changes in just this layer.
@@ -579,47 +567,86 @@ struct nsStyleBackground {
uint32_t mAttachmentCount,
mClipCount,
mOriginCount,
mRepeatCount,
mPositionCount,
mImageCount,
mSizeCount,
mBlendModeCount;
+
// Layers are stored in an array, matching the top-to-bottom order in
// which they are specified in CSS. The number of layers to be used
// should come from the background-image property. We create
// additional |Layer| objects for *any* property, not just
// background-image. This means that the bottommost layer that
// callers in layout care about (which is also the one whose
// background-clip applies to the background-color) may not be last
// layer. In layers below the bottom layer, properties will be
// uninitialized unless their count, above, indicates that they are
// present.
nsAutoTArray<Layer, 1> mLayers;
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
- #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
- for (uint32_t var_ = (stylebg_) ? (stylebg_)->mImageCount : 1; var_-- != 0; )
- #define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, stylebg_, start_, count_) \
- NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < ((stylebg_) ? (stylebg_)->mImageCount : 1), "Invalid layer start!"); \
+ void TrackImages(nsPresContext* aContext) {
+ for (uint32_t i = 0; i < mImageCount; ++i) {
+ mLayers[i].TrackImages(aContext);
+ }
+ }
+ void UntrackImages(nsPresContext* aContext) {
+ for (uint32_t i = 0; i < mImageCount; ++i)
+ mLayers[i].UntrackImages(aContext);
+ }
+
+ #define NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(var_, layers_) \
+ for (uint32_t var_ = layers_.mImageCount; var_-- != 0; )
+ #define NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
+ NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_.mImageCount), "Invalid layer start!"); \
NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
-
- nscolor mBackgroundColor; // [reset]
+};
+
+struct nsStyleBackground {
+ nsStyleBackground();
+ nsStyleBackground(const nsStyleBackground& aOther);
+ ~nsStyleBackground();
+
+ void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
+ return aContext->PresShell()->
+ AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
+ }
+ void Destroy(nsPresContext* aContext);
+
+ nsChangeHint CalcDifference(const nsStyleBackground& aOther) const;
+ static nsChangeHint MaxDifference() {
+ return nsChangeHint_UpdateEffects |
+ nsChangeHint_RepaintFrame |
+ nsChangeHint_SchedulePaint |
+ nsChangeHint_NeutralChange;
+ }
+ static nsChangeHint DifferenceAlwaysHandledForDescendants() {
+ // CalcDifference never returns the reflow hints that are sometimes
+ // handled for descendants at all.
+ return nsChangeHint(0);
+ }
// True if this background is completely transparent.
bool IsTransparent() const;
// We have to take slower codepaths for fixed background attachment,
// but we don't want to do that when there's no image.
// Not inline because it uses an nsCOMPtr<imgIRequest>
// FIXME: Should be in nsStyleStructInlines.h.
bool HasFixedBackground() const;
+
+ const nsStyleImageLayers::Layer& BottomLayer() const { return mLayers.BottomLayer(); }
+
+ nsStyleImageLayers mLayers;
+ nscolor mBackgroundColor; // [reset]
};
// See https://bugzilla.mozilla.org/show_bug.cgi?id=271586#c43 for why
// this is hard to replace with 'currentColor'.
#define BORDER_COLOR_FOREGROUND 0x20
#define OUTLINE_COLOR_INITIAL 0x80
// FOREGROUND | INITIAL(OUTLINE)
#define BORDER_COLOR_SPECIAL 0xA0
@@ -1397,19 +1424,19 @@ struct nsStylePosition {
}
static nsChangeHint DifferenceAlwaysHandledForDescendants() {
// CalcDifference can return all of the reflow hints that are
// sometimes handled for descendants as hints not handled for
// descendants.
return nsChangeHint(0);
}
- // XXXdholbert nsStyleBackground::Position should probably be moved to a
+ // XXXdholbert nsStyleImageLayers::Position should probably be moved to a
// different scope, since we're now using it in multiple style structs.
- typedef nsStyleBackground::Position Position;
+ typedef nsStyleImageLayers::Position Position;
/**
* Return the computed value for 'align-content'.
*/
uint16_t ComputedAlignContent() const { return mAlignContent; }
/**
* Return the computed value for 'align-items' given our 'display' value in
@@ -2209,20 +2236,20 @@ struct nsStyleDisplay {
}
static nsChangeHint DifferenceAlwaysHandledForDescendants() {
// CalcDifference can return all of the reflow hints that are
// sometimes handled for descendants as hints not handled for
// descendants.
return nsChangeHint(0);
}
- // XXXdholbert, XXXkgilbert nsStyleBackground::Position should probably be
+ // XXXdholbert, XXXkgilbert nsStyleImageLayers::Position should probably be
// moved to a different scope, since we're now using it in multiple style
// structs.
- typedef nsStyleBackground::Position Position;
+ typedef nsStyleImageLayers::Position Position;
// We guarantee that if mBinding is non-null, so are mBinding->GetURI() and
// mBinding->mOriginPrincipal.
RefPtr<mozilla::css::URLValue> mBinding; // [reset]
nsRect mClip; // [reset] offsets from upper-left border edge
float mOpacity; // [reset]
uint8_t mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
uint8_t mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed
@@ -3120,17 +3147,17 @@ public:
int32_t GetFillRule() const { return mFillRule; }
void SetFillRule(int32_t aFillRule)
{
NS_ASSERTION(mType == ePolygon, "expected polygon");
mFillRule = aFillRule;
}
- typedef nsStyleBackground::Position Position;
+ typedef nsStyleImageLayers::Position Position;
Position& GetPosition() {
NS_ASSERTION(mType == eCircle || mType == eEllipse,
"expected circle or ellipse");
return mPosition;
}
const Position& GetPosition() const {
NS_ASSERTION(mType == eCircle || mType == eEllipse,
"expected circle or ellipse");
--- a/layout/style/nsStyleUtil.cpp
+++ b/layout/style/nsStyleUtil.cpp
@@ -672,17 +672,17 @@ nsStyleUtil::IsSignificantChild(nsIConte
return aTextIsSignificant && isText && aChild->TextLength() != 0 &&
(aWhitespaceIsSignificant ||
!aChild->TextIsOnlyWhitespace());
}
// For a replaced element whose concrete object size is no larger than the
// element's content-box, this method checks whether the given
// "object-position" coordinate might cause overflow in its dimension.
-typedef nsStyleBackground::Position::PositionCoord PositionCoord;
+typedef nsStyleImageLayers::Position::PositionCoord PositionCoord;
static bool
ObjectPositionCoordMightCauseOverflow(const PositionCoord& aCoord)
{
// Any nonzero length in "object-position" can push us to overflow
// (particularly if our concrete object size is exactly the same size as the
// replaced element's content-box).
if (aCoord.mLength != 0) {
return true;
@@ -710,17 +710,17 @@ nsStyleUtil::ObjectPropsMightCauseOverfl
objectFit == NS_STYLE_OBJECT_FIT_NONE) {
return true;
}
// (All other object-fit values produce a concrete object size that's no larger
// than the constraint region.)
// Check each of our "object-position" coords to see if it could cause
// overflow in its dimension:
- const nsStyleBackground::Position& objectPosistion = aStylePos->mObjectPosition;
+ const nsStyleImageLayers::Position& objectPosistion = aStylePos->mObjectPosition;
if (ObjectPositionCoordMightCauseOverflow(objectPosistion.mXPosition) ||
ObjectPositionCoordMightCauseOverflow(objectPosistion.mYPosition)) {
return true;
}
return false;
}
--- a/layout/tables/nsTablePainter.cpp
+++ b/layout/tables/nsTablePainter.cpp
@@ -117,19 +117,19 @@ TableBackgroundPainter::TableBackgroundD
inline bool
TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder() const
{
/* we only need accurate border data when positioning background images*/
if (!mVisible) {
return false;
}
- const nsStyleBackground *bg = mFrame->StyleBackground();
- NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
- if (!bg->mLayers[i].mImage.IsEmpty())
+ const nsStyleImageLayers& layers = mFrame->StyleBackground()->mLayers;
+ NS_FOR_VISIBLE_IMAGELAYER_BACK_TO_FRONT(i, layers) {
+ if (!layers.mLayers[i].mImage.IsEmpty())
return true;
}
return false;
}
void
TableBackgroundPainter::TableBackgroundData::SetBCBorder(const nsMargin& aBorder)
{