summaryrefslogtreecommitdiff
path: root/layout
diff options
context:
space:
mode:
authorMoonchild <mcwerewolf@wolfbeast.com>2019-02-03 08:34:43 +0100
committerGitHub <noreply@github.com>2019-02-03 08:34:43 +0100
commit4874970d329943e08bcca7c61e7b7d2bc0f7c9d3 (patch)
tree4d1df04790cc8c785141e8dd8ffea9e6da5a0c02 /layout
parentfa311a4cae5ea526e848adc4f49c6aa0b700702c (diff)
parentb241a84d884293e1ce49a79c75e362c02c0899f9 (diff)
downloaduxp-4874970d329943e08bcca7c61e7b7d2bc0f7c9d3.tar.gz
Merge pull request #961 from kn-yami/issue908
implement missing parts of CSS mask
Diffstat (limited to 'layout')
-rw-r--r--layout/base/nsCSSRendering.cpp215
-rw-r--r--layout/base/nsDisplayList.cpp22
-rw-r--r--layout/base/nsDisplayList.h8
-rw-r--r--layout/base/nsLayoutUtils.cpp127
-rw-r--r--layout/base/nsLayoutUtils.h5
-rw-r--r--layout/generic/nsTextFrame.cpp2
-rw-r--r--layout/inspector/inDOMUtils.cpp2
-rw-r--r--layout/style/Declaration.cpp39
-rw-r--r--layout/style/StyleAnimationValue.cpp4
-rw-r--r--layout/style/nsCSSDataBlock.cpp2
-rw-r--r--layout/style/nsCSSKeywordList.h1
-rw-r--r--layout/style/nsCSSParser.cpp31
-rw-r--r--layout/style/nsCSSPropAliasList.h2
-rw-r--r--layout/style/nsCSSPropList.h20
-rw-r--r--layout/style/nsCSSProps.cpp62
-rw-r--r--layout/style/nsCSSProps.h3
-rw-r--r--layout/style/nsComputedDOMStyle.cpp60
-rw-r--r--layout/style/nsComputedDOMStyle.h12
-rw-r--r--layout/style/nsComputedDOMStylePropertyList.h2
-rw-r--r--layout/style/nsRuleNode.cpp40
-rw-r--r--layout/style/nsStyleConsts.h47
-rw-r--r--layout/style/nsStyleStruct.cpp8
-rw-r--r--layout/style/nsStyleStruct.h8
-rw-r--r--layout/svg/nsCSSClipPathInstance.cpp116
-rw-r--r--layout/svg/nsCSSClipPathInstance.h4
-rw-r--r--layout/svg/nsSVGIntegrationUtils.cpp144
-rw-r--r--layout/svg/nsSVGUtils.cpp21
27 files changed, 574 insertions, 433 deletions
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 71ebfad224..ff9edf7420 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1803,6 +1803,44 @@ SetupDirtyRects(const nsRect& aBGClipArea, const nsRect& aCallerDirtyRect,
"second should be empty if first is");
}
+static bool
+IsSVGStyleGeometryBox(StyleGeometryBox aBox)
+{
+ return (aBox == StyleGeometryBox::Fill || aBox == StyleGeometryBox::Stroke ||
+ aBox == StyleGeometryBox::View);
+}
+
+static bool
+IsHTMLStyleGeometryBox(StyleGeometryBox aBox)
+{
+ return (aBox == StyleGeometryBox::Content ||
+ aBox == StyleGeometryBox::Padding ||
+ aBox == StyleGeometryBox::Border ||
+ aBox == StyleGeometryBox::Margin);
+}
+
+static StyleGeometryBox
+ComputeBoxValue(nsIFrame* aForFrame, StyleGeometryBox aBox)
+{
+ // Except <svg>, all svg elements are not associate with CSS layout box.
+ if (aForFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (aForFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)) {
+ // For SVG elements without associated CSS layout box, the values
+ // content-box, padding-box, border-box and margin-box compute to fill-box.
+ if (IsHTMLStyleGeometryBox(aBox)) {
+ return StyleGeometryBox::Fill;
+ }
+ } else {
+ // For elements with associated CSS layout box, the values fill-box,
+ // stroke-box and view-box compute to the initial value of mask-clip.
+ if (IsSVGStyleGeometryBox(aBox)) {
+ return StyleGeometryBox::Border;
+ }
+ }
+
+ return aBox;
+}
+
/* static */ void
nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
nsIFrame* aForFrame, const nsStyleBorder& aBorder,
@@ -1810,6 +1848,55 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
bool aWillPaintBorder, nscoord aAppUnitsPerPixel,
/* out */ ImageLayerClipState* aClipState)
{
+ StyleGeometryBox layerClip = ComputeBoxValue(aForFrame, aLayer.mClip);
+
+ if (IsSVGStyleGeometryBox(layerClip)) {
+ MOZ_ASSERT(aForFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (aForFrame->GetType() != nsGkAtoms::svgOuterSVGFrame));
+
+ aClipState->mHasAdditionalBGClipArea = false;
+ aClipState->mCustomClip = false;
+
+ // The coordinate space of clipArea is svg user space.
+ nsRect clipArea =
+ nsLayoutUtils::ComputeGeometryBox(aForFrame, layerClip);
+
+ nsRect strokeBox = (layerClip == StyleGeometryBox::Stroke)
+ ? clipArea
+ : nsLayoutUtils::ComputeGeometryBox(aForFrame, StyleGeometryBox::Stroke);
+ nsRect clipAreaRelativeToStrokeBox = clipArea - strokeBox.TopLeft();
+
+ // aBorderArea is the stroke-box area in a coordinate space defined by
+ // the caller. This coordinate space can be svg user space of aForFrame,
+ // the space of aForFrame's reference-frame, or anything else.
+ //
+ // Which coordinate space chosen for aBorderArea is not matter. What
+ // matter is to ensure returning aClipState->mBGClipArea in the consistent
+ // coordiante space with aBorderArea. So we evaluate the position of clip
+ // area base on the position of aBorderArea here.
+ aClipState->mBGClipArea =
+ clipAreaRelativeToStrokeBox + aBorderArea.TopLeft();
+
+ SetupDirtyRects(aClipState->mBGClipArea, aCallerDirtyRect,
+ aAppUnitsPerPixel, &aClipState->mDirtyRect,
+ &aClipState->mDirtyRectGfx);
+ return;
+ }
+
+ if (layerClip == StyleGeometryBox::NoClip) {
+ aClipState->mBGClipArea = aCallerDirtyRect;
+ aClipState->mHasAdditionalBGClipArea = false;
+ aClipState->mCustomClip = false;
+
+ SetupDirtyRects(aClipState->mBGClipArea, aCallerDirtyRect,
+ aAppUnitsPerPixel, &aClipState->mDirtyRect,
+ &aClipState->mDirtyRectGfx);
+ return;
+ }
+
+ MOZ_ASSERT(!aForFrame->IsFrameOfType(nsIFrame::eSVG) ||
+ aForFrame->GetType() == nsGkAtoms::svgOuterSVGFrame);
+
// Compute the outermost boundary of the area that might be painted.
// Same coordinate space as aBorderArea.
Sides skipSides = aForFrame->GetSkipSides();
@@ -1819,16 +1906,15 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
bool haveRoundedCorners = GetRadii(aForFrame, aBorder, aBorderArea,
clipBorderArea, aClipState->mRadii);
- uint8_t backgroundClip = aLayer.mClip;
-
bool isSolidBorder =
aWillPaintBorder && IsOpaqueBorder(aBorder);
- if (isSolidBorder && backgroundClip == NS_STYLE_IMAGELAYER_CLIP_BORDER) {
+ if (isSolidBorder && layerClip == StyleGeometryBox::Border) {
// If we have rounded corners, we need to inflate the background
// drawing area a bit to avoid seams between the border and
// background.
- backgroundClip = haveRoundedCorners ?
- NS_STYLE_IMAGELAYER_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_IMAGELAYER_CLIP_PADDING;
+ layerClip = haveRoundedCorners
+ ? StyleGeometryBox::MozAlmostPadding
+ : StyleGeometryBox::Padding;
}
aClipState->mBGClipArea = clipBorderArea;
@@ -1844,7 +1930,7 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
// but the background is also clipped at a non-scrolling 'padding-box'
// like the content. (See below.)
// Therefore, only 'content-box' makes a difference here.
- if (backgroundClip == NS_STYLE_IMAGELAYER_CLIP_CONTENT) {
+ if (layerClip == StyleGeometryBox::Content) {
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
// Clip at a rectangle attached to the scrolled content.
aClipState->mHasAdditionalBGClipArea = true;
@@ -1864,22 +1950,30 @@ nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
// Also clip at a non-scrolling, rounded-corner 'padding-box',
// same as the scrolled content because of the 'overflow' property.
- backgroundClip = NS_STYLE_IMAGELAYER_CLIP_PADDING;
+ layerClip = StyleGeometryBox::Padding;
}
- if (backgroundClip != NS_STYLE_IMAGELAYER_CLIP_BORDER &&
- backgroundClip != NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ // See the comment of StyleGeometryBox::Margin.
+ // Hitting this assertion means we decide to turn on margin-box support for
+ // positioned mask from CSS parser and style system. In this case, you
+ // should *inflate* mBGClipArea by the margin returning from
+ // aForFrame->GetUsedMargin() in the code chunk bellow.
+ MOZ_ASSERT(layerClip != StyleGeometryBox::Margin,
+ "StyleGeometryBox::Margin rendering is not supported yet.\n");
+
+ if (layerClip != StyleGeometryBox::Border &&
+ layerClip != StyleGeometryBox::Text) {
nsMargin border = aForFrame->GetUsedBorder();
- if (backgroundClip == NS_STYLE_IMAGELAYER_CLIP_MOZ_ALMOST_PADDING) {
+ if (layerClip == StyleGeometryBox::MozAlmostPadding) {
// Reduce |border| by 1px (device pixels) on all sides, if
// possible, so that we don't get antialiasing seams between the
- // background and border.
+ // {background|mask} and border.
border.top = std::max(0, border.top - aAppUnitsPerPixel);
border.right = std::max(0, border.right - aAppUnitsPerPixel);
border.bottom = std::max(0, border.bottom - aAppUnitsPerPixel);
border.left = std::max(0, border.left - aAppUnitsPerPixel);
- } else if (backgroundClip != NS_STYLE_IMAGELAYER_CLIP_PADDING) {
- NS_ASSERTION(backgroundClip == NS_STYLE_IMAGELAYER_CLIP_CONTENT,
+ } else if (layerClip != StyleGeometryBox::Padding) {
+ NS_ASSERTION(layerClip == StyleGeometryBox::Content,
"unexpected background-clip");
border += aForFrame->GetUsedPadding();
}
@@ -3163,7 +3257,7 @@ nsCSSRendering::PaintBackgroundWithSC(const PaintBGParams& aParams,
if (drawBackgroundImage) {
bool clipSet = false;
- uint8_t currentBackgroundClip = NS_STYLE_IMAGELAYER_CLIP_BORDER;
+ StyleGeometryBox currentBackgroundClip = StyleGeometryBox::Border;
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, layers, layers.mImageCount - 1,
nLayers + (layers.mImageCount -
startLayer - 1)) {
@@ -3239,16 +3333,43 @@ nsCSSRendering::ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
nsIFrame** aAttachedToFrame,
bool* aOutIsTransformedFixed)
{
- // 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;
+ // Compute {background|mask} origin area relative to aBorderArea now as we
+ // may need it to compute the effective image size for a CSS gradient.
+ nsRect positionArea;
+
+ StyleGeometryBox layerOrigin =
+ ComputeBoxValue(aForFrame, aLayer.mOrigin);
+
+ if (IsSVGStyleGeometryBox(layerOrigin)) {
+ MOZ_ASSERT(aForFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (aForFrame->GetType() != nsGkAtoms::svgOuterSVGFrame));
+ *aAttachedToFrame = aForFrame;
+
+ positionArea =
+ nsLayoutUtils::ComputeGeometryBox(aForFrame, layerOrigin);
+
+ nsPoint toStrokeBoxOffset = nsPoint(0, 0);
+ if (layerOrigin != StyleGeometryBox::Stroke) {
+ nsRect strokeBox =
+ nsLayoutUtils::ComputeGeometryBox(aForFrame,
+ StyleGeometryBox::Stroke);
+ toStrokeBoxOffset = positionArea.TopLeft() - strokeBox.TopLeft();
+ }
+
+ // For SVG frames, the return value is relative to the stroke box
+ return nsRect(toStrokeBoxOffset, positionArea.Size());
+ }
+
+ MOZ_ASSERT(!aForFrame->IsFrameOfType(nsIFrame::eSVG) ||
+ aForFrame->GetType() == nsGkAtoms::svgOuterSVGFrame);
+
nsIAtom* frameType = aForFrame->GetType();
nsIFrame* geometryFrame = aForFrame;
if (MOZ_UNLIKELY(frameType == nsGkAtoms::scrollFrame &&
NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL == aLayer.mAttachment)) {
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
- bgPositioningArea = nsRect(
+ positionArea = nsRect(
scrollableFrame->GetScrolledFrame()->GetPosition()
// For the dir=rtl case:
+ scrollableFrame->GetScrollRange().TopLeft(),
@@ -3256,20 +3377,20 @@ nsCSSRendering::ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
// The ScrolledRect’s size does not include the borders or scrollbars,
// reverse the handling of background-origin
// compared to the common case below.
- if (aLayer.mOrigin == NS_STYLE_IMAGELAYER_ORIGIN_BORDER) {
+ if (layerOrigin == StyleGeometryBox::Border) {
nsMargin border = geometryFrame->GetUsedBorder();
border.ApplySkipSides(geometryFrame->GetSkipSides());
- bgPositioningArea.Inflate(border);
- bgPositioningArea.Inflate(scrollableFrame->GetActualScrollbarSizes());
- } else if (aLayer.mOrigin != NS_STYLE_IMAGELAYER_ORIGIN_PADDING) {
+ positionArea.Inflate(border);
+ positionArea.Inflate(scrollableFrame->GetActualScrollbarSizes());
+ } else if (layerOrigin != StyleGeometryBox::Padding) {
nsMargin padding = geometryFrame->GetUsedPadding();
padding.ApplySkipSides(geometryFrame->GetSkipSides());
- bgPositioningArea.Deflate(padding);
- NS_ASSERTION(aLayer.mOrigin == NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
+ positionArea.Deflate(padding);
+ NS_ASSERTION(layerOrigin == StyleGeometryBox::Content,
"unknown background-origin value");
}
*aAttachedToFrame = aForFrame;
- return bgPositioningArea;
+ return positionArea;
}
if (MOZ_UNLIKELY(frameType == nsGkAtoms::canvasFrame)) {
@@ -3279,25 +3400,31 @@ nsCSSRendering::ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
// finished and this page only displays the continuations of
// absolutely positioned content).
if (geometryFrame) {
- bgPositioningArea = geometryFrame->GetRect();
+ positionArea = geometryFrame->GetRect();
}
} else {
- bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
+ positionArea = nsRect(nsPoint(0,0), aBorderArea.Size());
}
- // Background images are tiled over the 'background-clip' area
- // but the origin of the tiling is based on the 'background-origin' area
- // XXX: Bug 1303623 will bring in new origin value, we should iterate from
- // NS_STYLE_IMAGELAYER_ORIGIN_MARGIN instead of
- // NS_STYLE_IMAGELAYER_ORIGIN_BORDER.
- if (aLayer.mOrigin != NS_STYLE_IMAGELAYER_ORIGIN_BORDER && geometryFrame) {
+ // See the comment of StyleGeometryBox::Margin.
+ // Hitting this assertion means we decide to turn on margin-box support for
+ // positioned mask from CSS parser and style system. In this case, you
+ // should *inflate* positionArea by the margin returning from
+ // geometryFrame->GetUsedMargin() in the code chunk bellow.
+ MOZ_ASSERT(aLayer.mOrigin != StyleGeometryBox::Margin,
+ "StyleGeometryBox::Margin rendering is not supported yet.\n");
+
+ // {background|mask} images are tiled over the '{background|mask}-clip' area
+ // but the origin of the tiling is based on the '{background|mask}-origin'
+ // area.
+ if (layerOrigin != StyleGeometryBox::Border && geometryFrame) {
nsMargin border = geometryFrame->GetUsedBorder();
- if (aLayer.mOrigin != NS_STYLE_IMAGELAYER_ORIGIN_PADDING) {
+ if (layerOrigin != StyleGeometryBox::Padding) {
border += geometryFrame->GetUsedPadding();
- NS_ASSERTION(aLayer.mOrigin == NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
+ NS_ASSERTION(layerOrigin == StyleGeometryBox::Content,
"unknown background-origin value");
}
- bgPositioningArea.Deflate(border);
+ positionArea.Deflate(border);
}
nsIFrame* attachedToFrame = aForFrame;
@@ -3325,7 +3452,7 @@ nsCSSRendering::ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
} else {
// Set the background positioning area to the viewport's area
// (relative to aForFrame)
- bgPositioningArea =
+ positionArea =
nsRect(-aForFrame->GetOffsetTo(attachedToFrame), attachedToFrame->GetSize());
if (!pageContentFrame) {
@@ -3334,14 +3461,14 @@ nsCSSRendering::ComputeImageLayerPositioningArea(nsPresContext* aPresContext,
aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
if (scrollableFrame) {
nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
- bgPositioningArea.Deflate(scrollbars);
+ positionArea.Deflate(scrollbars);
}
}
}
}
*aAttachedToFrame = attachedToFrame;
- return bgPositioningArea;
+ return positionArea;
}
// Implementation of the formula for computation of background-repeat round
@@ -3569,7 +3696,7 @@ nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
bool transformedFixed = false;
// 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 =
+ nsRect positionArea =
ComputeImageLayerPositioningArea(aPresContext, aForFrame, aBorderArea,
aLayer, &attachedToFrame, &transformedFixed);
if (aOutIsTransformedFixed) {
@@ -3594,7 +3721,7 @@ nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
// not a pure optimization since it can affect the values of pixels at the
// edge of the viewport --- whether they're sampled from a putative "next
// tile" or not.)
- bgClipRect.IntersectRect(bgClipRect, bgPositioningArea + aBorderArea.TopLeft());
+ bgClipRect.IntersectRect(bgClipRect, positionArea + aBorderArea.TopLeft());
}
}
@@ -3605,7 +3732,7 @@ nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
// Also as required for proper background positioning when background-position
// is defined with percentages.
CSSSizeOrRatio intrinsicSize = state.mImageRenderer.ComputeIntrinsicSize();
- nsSize bgPositionSize = bgPositioningArea.Size();
+ nsSize bgPositionSize = positionArea.Size();
nsSize imageSize = ComputeDrawnSizeForBackground(intrinsicSize,
bgPositionSize,
aLayer.mSize,
@@ -3650,8 +3777,8 @@ nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
}
}
- imageTopLeft += bgPositioningArea.TopLeft();
- state.mAnchor += bgPositioningArea.TopLeft();
+ imageTopLeft += positionArea.TopLeft();
+ state.mAnchor += positionArea.TopLeft();
state.mDestArea = nsRect(imageTopLeft + aBorderArea.TopLeft(), imageSize);
state.mFillArea = state.mDestArea;
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index 2b9ad7ff81..d619576baf 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3014,7 +3014,7 @@ nsDisplayBackgroundImage::ComputeVisibility(nsDisplayListBuilder* aBuilder,
/* static */ nsRegion
nsDisplayBackgroundImage::GetInsideClipRegion(nsDisplayItem* aItem,
- uint8_t aClip,
+ StyleGeometryBox aClip,
const nsRect& aRect,
const nsRect& aBackgroundRect)
{
@@ -3028,10 +3028,10 @@ nsDisplayBackgroundImage::GetInsideClipRegion(nsDisplayItem* aItem,
if (frame->GetType() == nsGkAtoms::canvasFrame) {
nsCanvasFrame* canvasFrame = static_cast<nsCanvasFrame*>(frame);
clipRect = canvasFrame->CanvasArea() + aItem->ToReferenceFrame();
- } else if (aClip == NS_STYLE_IMAGELAYER_CLIP_PADDING ||
- aClip == NS_STYLE_IMAGELAYER_CLIP_CONTENT) {
+ } else if (aClip == StyleGeometryBox::Padding ||
+ aClip == StyleGeometryBox::Content) {
nsMargin border = frame->GetUsedBorder();
- if (aClip == NS_STYLE_IMAGELAYER_CLIP_CONTENT) {
+ if (aClip == StyleGeometryBox::Content) {
border += frame->GetUsedPadding();
}
border.ApplySkipSides(frame->GetSkipSides());
@@ -3064,7 +3064,7 @@ nsDisplayBackgroundImage::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
if (layer.mImage.IsOpaque() && layer.mBlendMode == NS_STYLE_BLEND_NORMAL &&
layer.mRepeat.mXRepeat != NS_STYLE_IMAGELAYER_REPEAT_SPACE &&
layer.mRepeat.mYRepeat != NS_STYLE_IMAGELAYER_REPEAT_SPACE &&
- layer.mClip != NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ layer.mClip != StyleGeometryBox::Text) {
result = GetInsideClipRegion(this, layer.mClip, mBounds, mBackgroundRect);
}
}
@@ -3143,9 +3143,9 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
CheckForBorderItem(this, flags);
gfxContext* ctx = aCtx->ThebesContext();
- uint8_t clip = mBackgroundStyle->mImage.mLayers[mLayer].mClip;
+ StyleGeometryBox clip = mBackgroundStyle->mImage.mLayers[mLayer].mClip;
- if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ if (clip == StyleGeometryBox::Text) {
if (!GenerateAndPushTextMask(mFrame, aCtx, mBackgroundRect, aBuilder)) {
return;
}
@@ -3161,7 +3161,7 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
image::DrawResult result =
nsCSSRendering::PaintBackground(params);
- if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ if (clip == StyleGeometryBox::Text) {
ctx->PopGroupAndBlend();
}
@@ -3583,8 +3583,8 @@ nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
nsLayoutUtils::RectToGfxRect(mBackgroundRect,
mFrame->PresContext()->AppUnitsPerDevPixel());
- uint8_t clip = mBackgroundStyle->mImage.mLayers[0].mClip;
- if (clip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ StyleGeometryBox clip = mBackgroundStyle->mImage.mLayers[0].mClip;
+ if (clip == StyleGeometryBox::Text) {
if (!GenerateAndPushTextMask(mFrame, aCtx, mBackgroundRect, aBuilder)) {
return;
}
@@ -3618,7 +3618,7 @@ nsDisplayBackgroundColor::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
const nsStyleImageLayers::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
- if (bottomLayer.mClip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ if (bottomLayer.mClip == StyleGeometryBox::Text) {
return nsRegion();
}
diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h
index 9603a95b81..c9f773f5b6 100644
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2713,6 +2713,8 @@ private:
*/
class nsDisplayBackgroundImage : public nsDisplayImageContainer {
public:
+ typedef mozilla::StyleGeometryBox StyleGeometryBox;
+
/**
* aLayer signifies which background layer this item represents.
* aIsThemed should be the value of aFrame->IsThemed.
@@ -2790,8 +2792,10 @@ public:
virtual already_AddRefed<imgIContainer> GetImage() override;
virtual nsRect GetDestRect() override;
- static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, uint8_t aClip,
- const nsRect& aRect, const nsRect& aBackgroundRect);
+ static nsRegion GetInsideClipRegion(nsDisplayItem* aItem,
+ StyleGeometryBox aClip,
+ const nsRect& aRect,
+ const nsRect& aBackgroundRect);
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override;
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 19200d5a72..f0341f9eff 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -117,6 +117,7 @@
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "RegionBuilder.h"
+#include "SVGSVGElement.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
@@ -6935,7 +6936,7 @@ nsLayoutUtils::GetFrameTransparency(nsIFrame* aBackgroundFrame,
const nsStyleBackground* bg = bgSC->StyleBackground();
if (NS_GET_A(bg->mBackgroundColor) < 255 ||
// bottom layer's clip is used for the color
- bg->BottomLayer().mClip != NS_STYLE_IMAGELAYER_CLIP_BORDER)
+ bg->BottomLayer().mClip != StyleGeometryBox::Border)
return eTransparencyTransparent;
return eTransparencyOpaque;
}
@@ -9293,3 +9294,127 @@ nsLayoutUtils::IsInvisibleBreak(nsINode* aNode, nsIFrame** aNextLineFrame)
return lineNonEmpty;
}
+
+static nsRect
+ComputeSVGReferenceRect(nsIFrame* aFrame,
+ StyleGeometryBox aGeometryBox)
+{
+ MOZ_ASSERT(aFrame->GetContent()->IsSVGElement());
+ nsRect r;
+
+ // For SVG elements without associated CSS layout box, the used value for
+ // content-box, padding-box, border-box and margin-box is fill-box.
+ switch (aGeometryBox) {
+ case StyleGeometryBox::Stroke: {
+ // XXX Bug 1299876
+ // The size of srtoke-box is not correct if this graphic element has
+ // specific stroke-linejoin or stroke-linecap.
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ case StyleGeometryBox::View: {
+ nsIContent* content = aFrame->GetContent();
+ nsSVGElement* element = static_cast<nsSVGElement*>(content);
+ SVGSVGElement* svgElement = element->GetCtx();
+ MOZ_ASSERT(svgElement);
+
+ if (svgElement && svgElement->HasViewBoxRect()) {
+ // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
+ // element:
+ // 1. The reference box is positioned at the origin of the coordinate
+ // system established by the ‘viewBox‘ attribute.
+ // 2. The dimension of the reference box is set to the width and height
+ // values of the ‘viewBox‘ attribute.
+ nsSVGViewBox* viewBox = svgElement->GetViewBox();
+ const nsSVGViewBoxRect& value = viewBox->GetAnimValue();
+ r = nsRect(nsPresContext::CSSPixelsToAppUnits(value.x),
+ nsPresContext::CSSPixelsToAppUnits(value.y),
+ nsPresContext::CSSPixelsToAppUnits(value.width),
+ nsPresContext::CSSPixelsToAppUnits(value.height));
+ } else {
+ // No viewBox is specified, uses the nearest SVG viewport as reference
+ // box.
+ svgFloatSize viewportSize = svgElement->GetViewportSize();
+ r = nsRect(0, 0,
+ nsPresContext::CSSPixelsToAppUnits(viewportSize.width),
+ nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
+ }
+
+ break;
+ }
+ case StyleGeometryBox::NoBox:
+ case StyleGeometryBox::Border:
+ case StyleGeometryBox::Content:
+ case StyleGeometryBox::Padding:
+ case StyleGeometryBox::Margin:
+ case StyleGeometryBox::Fill: {
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ default:{
+ MOZ_ASSERT_UNREACHABLE("unknown StyleGeometryBox type");
+ gfxRect bbox = nsSVGUtils::GetBBox(aFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ }
+
+ return r;
+}
+
+static nsRect
+ComputeHTMLReferenceRect(nsIFrame* aFrame,
+ StyleGeometryBox aGeometryBox)
+{
+ nsRect r;
+
+ // For elements with associated CSS layout box, the used value for fill-box,
+ // stroke-box and view-box is border-box.
+ switch (aGeometryBox) {
+ case StyleGeometryBox::Content:
+ r = aFrame->GetContentRectRelativeToSelf();
+ break;
+ case StyleGeometryBox::Padding:
+ r = aFrame->GetPaddingRectRelativeToSelf();
+ break;
+ case StyleGeometryBox::Margin:
+ r = aFrame->GetMarginRectRelativeToSelf();
+ break;
+ case StyleGeometryBox::NoBox:
+ case StyleGeometryBox::Border:
+ case StyleGeometryBox::Fill:
+ case StyleGeometryBox::Stroke:
+ case StyleGeometryBox::View:
+ r = aFrame->GetRectRelativeToSelf();
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("unknown StyleGeometryBox type");
+ r = aFrame->GetRectRelativeToSelf();
+ break;
+ }
+
+ return r;
+}
+
+/* static */ nsRect
+nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame,
+ StyleGeometryBox aGeometryBox)
+{
+ // We use ComputeSVGReferenceRect for all SVG elements, except <svg>
+ // element, which does have an associated CSS layout box. In this case we
+ // should still use ComputeHTMLReferenceRect for region computing.
+ nsRect r = aFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (aFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)
+ ? ComputeSVGReferenceRect(aFrame, aGeometryBox)
+ : ComputeHTMLReferenceRect(aFrame, aGeometryBox);
+
+ return r;
+}
diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
index 97fc410b0a..63253fd100 100644
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -30,6 +30,7 @@
#include "mozilla/ReflowOutput.h"
#include "ImageContainer.h"
#include "gfx2DGlue.h"
+#include "nsStyleConsts.h"
#include <limits>
#include <algorithm>
@@ -152,6 +153,7 @@ public:
typedef mozilla::CSSRect CSSRect;
typedef mozilla::ScreenMargin ScreenMargin;
typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
+ typedef mozilla::StyleGeometryBox StyleGeometryBox;
/**
* Finds previously assigned ViewID for the given content element, if any.
@@ -2870,6 +2872,9 @@ public:
*/
static bool IsInvisibleBreak(nsINode* aNode, nsIFrame** aNextLineFrame = nullptr);
+ static nsRect ComputeGeometryBox(nsIFrame* aFrame,
+ StyleGeometryBox aGeometryBox);
+
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index fa31443fdd..3288d3f2e4 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -6715,7 +6715,7 @@ ShouldDrawSelection(const nsIFrame* aFrame)
const nsStyleBackground* bg = aFrame->StyleContext()->StyleBackground();
const nsStyleImageLayers& layers = bg->mImage;
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) {
- if (layers.mLayers[i].mClip == NS_STYLE_IMAGELAYER_CLIP_TEXT) {
+ if (layers.mLayers[i].mClip == StyleGeometryBox::Text) {
return false;
}
}
diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp
index 9f1dcaad3f..e212e20df0 100644
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -784,12 +784,10 @@ PropertySupportsVariant(nsCSSPropertyID aPropertyID, uint32_t aVariant)
case eCSSProperty_background_position_x:
case eCSSProperty_background_position_y:
case eCSSProperty_background_size:
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask_position:
case eCSSProperty_mask_position_x:
case eCSSProperty_mask_position_y:
case eCSSProperty_mask_size:
-#endif
case eCSSProperty_grid_auto_columns:
case eCSSProperty_grid_auto_rows:
case eCSSProperty_grid_template_columns:
diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp
index c67f6b2a2e..b2de159ed3 100644
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -395,28 +395,25 @@ Declaration::GetImageLayerValue(
origin->mValue.GetUnit() == eCSSUnit_Enumerated,
"should not have inherit/initial within list");
- int32_t originDefaultValue =
+ StyleGeometryBox originDefaultValue =
(aTable == nsStyleImageLayers::kBackgroundLayerTable)
- ? NS_STYLE_IMAGELAYER_ORIGIN_PADDING : NS_STYLE_IMAGELAYER_ORIGIN_BORDER;
- if (clip->mValue.GetIntValue() != NS_STYLE_IMAGELAYER_CLIP_BORDER ||
- origin->mValue.GetIntValue() != originDefaultValue) {
+ ? StyleGeometryBox::Padding : StyleGeometryBox::Border;
+ if (static_cast<StyleGeometryBox>(clip->mValue.GetIntValue()) !=
+ StyleGeometryBox::Border ||
+ static_cast<StyleGeometryBox>(origin->mValue.GetIntValue()) !=
+ originDefaultValue) {
#ifdef DEBUG
- for (size_t i = 0; nsCSSProps::kImageLayerOriginKTable[i].mValue != -1; i++) {
+ const nsCSSProps::KTableEntry* originTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::origin]];
+ const nsCSSProps::KTableEntry* clipTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::clip]];
+ for (size_t i = 0; originTable[i].mValue != -1; i++) {
// For each keyword & value in kOriginKTable, ensure that
// kBackgroundKTable has a matching entry at the same position.
- MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mKeyword ==
- nsCSSProps::kBackgroundClipKTable[i].mKeyword);
- MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mValue ==
- nsCSSProps::kBackgroundClipKTable[i].mValue);
+ MOZ_ASSERT(originTable[i].mKeyword == clipTable[i].mKeyword);
+ MOZ_ASSERT(originTable[i].mValue == clipTable[i].mValue);
}
#endif
- static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER ==
- NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
- NS_STYLE_IMAGELAYER_CLIP_PADDING ==
- NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
- NS_STYLE_IMAGELAYER_CLIP_CONTENT ==
- NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
- "mask-clip and mask-origin style constants must agree");
aValue.Append(char16_t(' '));
origin->mValue.AppendToString(aTable[nsStyleImageLayers::origin], aValue,
aSerialization);
@@ -462,11 +459,7 @@ Declaration::GetImageLayerValue(
}
// This layer is an mask layer
} else {
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
MOZ_ASSERT(aTable == nsStyleImageLayers::kMaskLayerTable);
-#else
- MOZ_ASSERT_UNREACHABLE("Should never get here when mask-as-shorthand is disable");
-#endif
if (repeat || positionX || positionY || clip || origin || size ||
composite || mode) {
// Uneven length lists, so can't be serialized as shorthand.
@@ -487,11 +480,7 @@ Declaration::GetImageLayerValue(
}
// This layer is an mask layer
} else {
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
MOZ_ASSERT(aTable == nsStyleImageLayers::kMaskLayerTable);
-#else
- MOZ_ASSERT_UNREACHABLE("Should never get here when mask-as-shorthand is disable");
-#endif
if (!repeat || !positionX || !positionY || !clip || !origin || !size ||
!composite || !mode) {
// Uneven length lists, so can't be serialized as shorthand.
@@ -817,7 +806,6 @@ Declaration::GetPropertyValueInternal(
nsStyleImageLayers::kBackgroundLayerTable);
break;
}
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask: {
GetImageLayerValue(data, aValue, aSerialization,
nsStyleImageLayers::kMaskLayerTable);
@@ -828,7 +816,6 @@ Declaration::GetPropertyValueInternal(
nsStyleImageLayers::kMaskLayerTable);
break;
}
-#endif
case eCSSProperty_font: {
// systemFont might not be present; other values are guaranteed to be
// available based on the shorthand check at the beginning of the
diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp
index eb34c3d832..a0f52b4ea1 100644
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -4255,7 +4255,6 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
}
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask_position_x: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
@@ -4269,21 +4268,18 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
break;
}
-#endif
case eCSSProperty_background_size: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerSizePairList(layers, aComputedValue);
break;
}
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask_size: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerSizePairList(layers, aComputedValue);
break;
}
-#endif
case eCSSProperty_clip_path: {
const nsStyleSVGReset* svgReset =
diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp
index fe2dc621a5..1dfdaed0ee 100644
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -61,7 +61,6 @@ TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
MOZ_ASSERT(aDocument);
if (aValue.GetUnit() == eCSSUnit_URL) {
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
// The 'mask-image' property accepts local reference URIs.
// For example,
// mask-image: url(#mask_id); // refer to a SVG mask element, whose id is
@@ -94,7 +93,6 @@ TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
}
}
}
-#endif
aValue.StartImageLoad(aDocument);
if (aForTokenStream && aContext) {
CSSVariableImageTable::Add(aContext, aProperty,
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h
index 94968faca3..34a46ffceb 100644
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -405,6 +405,7 @@ CSS_KEY(n-resize, n_resize)
CSS_KEY(narrower, narrower)
CSS_KEY(ne-resize, ne_resize)
CSS_KEY(nesw-resize, nesw_resize)
+CSS_KEY(no-clip, no_clip)
CSS_KEY(no-close-quote, no_close_quote)
CSS_KEY(no-common-ligatures, no_common_ligatures)
CSS_KEY(no-contextual, no_contextual)
diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 736c66f87a..a8309314f8 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -12005,7 +12005,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSPropertyID aPropID)
return ParsePaintOrder();
case eCSSProperty_scroll_snap_type:
return ParseScrollSnapType();
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
case eCSSProperty_mask:
return ParseImageLayers(nsStyleImageLayers::kMaskLayerTable);
case eCSSProperty_mask_repeat:
@@ -12018,7 +12017,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSPropertyID aPropID)
aPropID == eCSSProperty_mask_position_x);
case eCSSProperty_mask_size:
return ParseImageLayerSize(eCSSProperty_mask_size);
-#endif
case eCSSProperty__webkit_text_stroke:
return ParseWebkitTextStroke();
case eCSSProperty_all:
@@ -12424,7 +12422,7 @@ CSSParserImpl::ParseImageLayersItem(
aState.mImage->mValue.SetNoneValue();
aState.mAttachment->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL,
eCSSUnit_Enumerated);
- aState.mClip->mValue.SetIntValue(NS_STYLE_IMAGELAYER_CLIP_BORDER,
+ aState.mClip->mValue.SetIntValue(StyleGeometryBox::Border,
eCSSUnit_Enumerated);
aState.mRepeat->mXValue.SetIntValue(NS_STYLE_IMAGELAYER_REPEAT_REPEAT,
@@ -12437,10 +12435,10 @@ CSSParserImpl::ParseImageLayersItem(
aState.mPositionY->mValue.SetArrayValue(positionYArr, eCSSUnit_Array);
if (eCSSProperty_mask == aTable[nsStyleImageLayers::shorthand]) {
- aState.mOrigin->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ORIGIN_BORDER,
+ aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Border,
eCSSUnit_Enumerated);
} else {
- aState.mOrigin->mValue.SetIntValue(NS_STYLE_IMAGELAYER_ORIGIN_PADDING,
+ aState.mOrigin->mValue.SetIntValue(StyleGeometryBox::Padding,
eCSSUnit_Enumerated);
}
positionXArr->Item(1).SetPercentValue(0.0f);
@@ -12462,6 +12460,8 @@ CSSParserImpl::ParseImageLayersItem(
haveMode = false,
haveSomething = false;
+ const KTableEntry* originTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::origin]];
while (GetToken(true)) {
nsCSSTokenType tt = mToken.mType;
UngetToken(); // ...but we'll still cheat and use mToken
@@ -12531,8 +12531,7 @@ CSSParserImpl::ParseImageLayersItem(
aState.mSize->mXValue = scratch.mXValue;
aState.mSize->mYValue = scratch.mYValue;
}
- } else if (nsCSSProps::FindKeyword(keyword,
- nsCSSProps::kImageLayerOriginKTable, dummy)) {
+ } else if (nsCSSProps::FindKeyword(keyword, originTable, dummy)) {
if (haveOrigin)
return false;
haveOrigin = true;
@@ -12547,23 +12546,15 @@ CSSParserImpl::ParseImageLayersItem(
// immediately following the first one (for background-origin).
#ifdef DEBUG
- for (size_t i = 0; nsCSSProps::kImageLayerOriginKTable[i].mValue != -1; i++) {
+ const KTableEntry* clipTable =
+ nsCSSProps::kKeywordTableTable[aTable[nsStyleImageLayers::clip]];
+ for (size_t i = 0; originTable[i].mValue != -1; i++) {
// For each keyword & value in kOriginKTable, ensure that
// kBackgroundKTable has a matching entry at the same position.
- MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mKeyword ==
- nsCSSProps::kBackgroundClipKTable[i].mKeyword);
- MOZ_ASSERT(nsCSSProps::kImageLayerOriginKTable[i].mValue ==
- nsCSSProps::kBackgroundClipKTable[i].mValue);
+ MOZ_ASSERT(originTable[i].mKeyword == clipTable[i].mKeyword);
+ MOZ_ASSERT(originTable[i].mValue == clipTable[i].mValue);
}
#endif
- static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER ==
- NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
- NS_STYLE_IMAGELAYER_CLIP_PADDING ==
- NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
- NS_STYLE_IMAGELAYER_CLIP_CONTENT ==
- NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
- "bg-clip and bg-origin style constants must agree");
-
CSSParseResult result =
ParseSingleValueProperty(aState.mClip->mValue,
aTable[nsStyleImageLayers::clip]);
diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h
index 2699549ffc..f7938af9ed 100644
--- a/layout/style/nsCSSPropAliasList.h
+++ b/layout/style/nsCSSPropAliasList.h
@@ -453,7 +453,6 @@ CSS_PROP_ALIAS(-webkit-user-select,
WebkitUserSelect,
WEBKIT_PREFIX_PREF)
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
CSS_PROP_ALIAS(-webkit-mask,
mask,
WebkitMask,
@@ -494,5 +493,4 @@ CSS_PROP_ALIAS(-webkit-mask-size,
mask_size,
WebkitMaskSize,
WEBKIT_PREFIX_PREF)
-#endif
#undef WEBKIT_PREFIX_PREF
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index b04921dcb5..2049f70e88 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -564,7 +564,7 @@ CSS_PROP_BACKGROUND(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
"",
VARIANT_KEYWORD, // used by list parsing
- kImageLayerOriginKTable,
+ kBackgroundOriginKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
CSS_PROP_SHORTHAND(
@@ -2645,19 +2645,6 @@ CSS_PROP_SVG(
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
-#ifndef MOZ_ENABLE_MASK_AS_SHORTHAND
-CSS_PROP_SVGRESET(
- mask,
- mask,
- Mask,
- CSS_PROPERTY_PARSE_VALUE |
- CSS_PROPERTY_CREATES_STACKING_CONTEXT,
- "",
- VARIANT_HUO,
- nullptr,
- CSS_PROP_NO_OFFSET,
- eStyleAnimType_Discrete)
-#else
CSS_PROP_SHORTHAND(
mask,
mask,
@@ -2672,7 +2659,7 @@ CSS_PROP_SVGRESET(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
"",
VARIANT_KEYWORD, // used by list parsing
- kImageLayerOriginKTable,
+ kMaskClipKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
CSS_PROP_SVGRESET(
@@ -2718,7 +2705,7 @@ CSS_PROP_SVGRESET(
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
"",
VARIANT_KEYWORD, // used by list parsing
- kImageLayerOriginKTable,
+ kMaskOriginKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
CSS_PROP_SHORTHAND(
@@ -2776,7 +2763,6 @@ CSS_PROP_SVGRESET(
kImageLayerSizeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Custom)
-#endif // MOZ_ENABLE_MASK_AS_SHORTHAND
CSS_PROP_SVGRESET(
mask-type,
mask_type,
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index 9805eae14e..ac2978c277 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -932,33 +932,43 @@ const KTableEntry nsCSSProps::kImageLayerAttachmentKTable[] = {
{ eCSSKeyword_UNKNOWN, -1 }
};
-static_assert(NS_STYLE_IMAGELAYER_CLIP_BORDER == NS_STYLE_IMAGELAYER_ORIGIN_BORDER &&
- NS_STYLE_IMAGELAYER_CLIP_PADDING == NS_STYLE_IMAGELAYER_ORIGIN_PADDING &&
- NS_STYLE_IMAGELAYER_CLIP_CONTENT == NS_STYLE_IMAGELAYER_ORIGIN_CONTENT,
- "Except background-clip:text, all {background,mask}-clip and "
- "{background,mask}-origin style constants must agree");
-
-const KTableEntry nsCSSProps::kImageLayerOriginKTable[] = {
- { eCSSKeyword_border_box, NS_STYLE_IMAGELAYER_ORIGIN_BORDER },
- { eCSSKeyword_padding_box, NS_STYLE_IMAGELAYER_ORIGIN_PADDING },
- { eCSSKeyword_content_box, NS_STYLE_IMAGELAYER_ORIGIN_CONTENT },
+const KTableEntry nsCSSProps::kBackgroundOriginKTable[] = {
+ { eCSSKeyword_border_box, StyleGeometryBox::Border },
+ { eCSSKeyword_padding_box, StyleGeometryBox::Padding },
+ { eCSSKeyword_content_box, StyleGeometryBox::Content },
{ eCSSKeyword_UNKNOWN, -1 }
};
KTableEntry nsCSSProps::kBackgroundClipKTable[] = {
- { eCSSKeyword_border_box, NS_STYLE_IMAGELAYER_CLIP_BORDER },
- { eCSSKeyword_padding_box, NS_STYLE_IMAGELAYER_CLIP_PADDING },
- { eCSSKeyword_content_box, NS_STYLE_IMAGELAYER_CLIP_CONTENT },
+ { eCSSKeyword_border_box, StyleGeometryBox::Border },
+ { eCSSKeyword_padding_box, StyleGeometryBox::Padding },
+ { eCSSKeyword_content_box, StyleGeometryBox::Content },
// The next entry is controlled by the layout.css.background-clip-text.enabled
// pref.
- { eCSSKeyword_text, NS_STYLE_IMAGELAYER_CLIP_TEXT },
+ { eCSSKeyword_text, StyleGeometryBox::Text },
{ eCSSKeyword_UNKNOWN, -1 }
};
-static_assert(MOZ_ARRAY_LENGTH(nsCSSProps::kImageLayerOriginKTable) ==
- MOZ_ARRAY_LENGTH(nsCSSProps::kBackgroundClipKTable) - 1,
- "background-clip has one extra value, which is text, compared"
- "to {background,mask}-origin");
+const KTableEntry nsCSSProps::kMaskOriginKTable[] = {
+ { eCSSKeyword_border_box, StyleGeometryBox::Border },
+ { eCSSKeyword_padding_box, StyleGeometryBox::Padding },
+ { eCSSKeyword_content_box, StyleGeometryBox::Content },
+ { eCSSKeyword_fill_box, StyleGeometryBox::Fill },
+ { eCSSKeyword_stroke_box, StyleGeometryBox::Stroke },
+ { eCSSKeyword_view_box, StyleGeometryBox::View },
+ { eCSSKeyword_UNKNOWN, -1 }
+};
+
+const KTableEntry nsCSSProps::kMaskClipKTable[] = {
+ { eCSSKeyword_border_box, StyleGeometryBox::Border },
+ { eCSSKeyword_padding_box, StyleGeometryBox::Padding },
+ { eCSSKeyword_content_box, StyleGeometryBox::Content },
+ { eCSSKeyword_fill_box, StyleGeometryBox::Fill },
+ { eCSSKeyword_stroke_box, StyleGeometryBox::Stroke },
+ { eCSSKeyword_view_box, StyleGeometryBox::View },
+ { eCSSKeyword_no_clip, StyleGeometryBox::NoClip },
+ { eCSSKeyword_UNKNOWN, -1 }
+};
// Note: Don't change this table unless you update
// ParseImageLayerPosition!
@@ -2346,13 +2356,13 @@ const KTableEntry nsCSSProps::kFillRuleKTable[] = {
};
const KTableEntry nsCSSProps::kClipPathGeometryBoxKTable[] = {
- { eCSSKeyword_content_box, StyleClipPathGeometryBox::Content },
- { eCSSKeyword_padding_box, StyleClipPathGeometryBox::Padding },
- { eCSSKeyword_border_box, StyleClipPathGeometryBox::Border },
- { eCSSKeyword_margin_box, StyleClipPathGeometryBox::Margin },
- { eCSSKeyword_fill_box, StyleClipPathGeometryBox::Fill },
- { eCSSKeyword_stroke_box, StyleClipPathGeometryBox::Stroke },
- { eCSSKeyword_view_box, StyleClipPathGeometryBox::View },
+ { eCSSKeyword_content_box, StyleGeometryBox::Content },
+ { eCSSKeyword_padding_box, StyleGeometryBox::Padding },
+ { eCSSKeyword_border_box, StyleGeometryBox::Border },
+ { eCSSKeyword_margin_box, StyleGeometryBox::Margin },
+ { eCSSKeyword_fill_box, StyleGeometryBox::Fill },
+ { eCSSKeyword_stroke_box, StyleGeometryBox::Stroke },
+ { eCSSKeyword_view_box, StyleGeometryBox::View },
{ eCSSKeyword_UNKNOWN, -1 }
};
@@ -3051,7 +3061,6 @@ static const nsCSSPropertyID gScrollSnapTypeSubpropTable[] = {
eCSSProperty_scroll_snap_type_y,
eCSSProperty_UNKNOWN
};
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
static const nsCSSPropertyID gMaskSubpropTable[] = {
eCSSProperty_mask_image,
eCSSProperty_mask_repeat,
@@ -3069,7 +3078,6 @@ static const nsCSSPropertyID gMaskPositionSubpropTable[] = {
eCSSProperty_mask_position_y,
eCSSProperty_UNKNOWN
};
-#endif
// FIXME: mask-border tables should be added when we implement
// mask-border properties.
diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h
index dfe35afd82..e67e1d41d1 100644
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -717,6 +717,8 @@ public:
static const KTableEntry kTransformStyleKTable[];
static const KTableEntry kImageLayerAttachmentKTable[];
static const KTableEntry kImageLayerOriginKTable[];
+ static const KTableEntry kBackgroundOriginKTable[];
+ static const KTableEntry kMaskOriginKTable[];
static const KTableEntry kImageLayerPositionKTable[];
static const KTableEntry kImageLayerRepeatKTable[];
static const KTableEntry kImageLayerRepeatPartKTable[];
@@ -726,6 +728,7 @@ public:
// Not const because we modify its entries when the pref
// "layout.css.background-clip.text" changes:
static KTableEntry kBackgroundClipKTable[];
+ static const KTableEntry kMaskClipKTable[];
static const KTableEntry kBlendModeKTable[];
static const KTableEntry kBorderCollapseKTable[];
static const KTableEntry kBorderImageRepeatKTable[];
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index 4f8d3edf66..36c3a63857 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -74,6 +74,30 @@ NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt,
return computedStyle.forget();
}
+static nsDOMCSSValueList*
+GetROCSSValueList(bool aCommaDelimited)
+{
+ return new nsDOMCSSValueList(aCommaDelimited, true);
+}
+
+template<typename T>
+already_AddRefed<CSSValue>
+GetBackgroundList(T nsStyleImageLayers::Layer::* aMember,
+ uint32_t nsStyleImageLayers::* aCount,
+ const nsStyleImageLayers& aLayers,
+ const KTableEntry aTable[])
+{
+ RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
+
+ for (uint32_t i = 0, i_end = aLayers.*aCount; i < i_end; ++i) {
+ RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+ val->SetIdent(nsCSSProps::ValueToKeywordEnum(aLayers.mLayers[i].*aMember, aTable));
+ valueList->AppendCSSValue(val.forget());
+ }
+
+ return valueList.forget();
+}
+
/**
* An object that represents the ordered set of properties that are exposed on
* an nsComputedDOMStyle object and how their computed values can be obtained.
@@ -1803,24 +1827,6 @@ nsComputedDOMStyle::DoGetFontVariantPosition()
}
already_AddRefed<CSSValue>
-nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleImageLayers::Layer::* aMember,
- uint32_t nsStyleImageLayers::* aCount,
- const nsStyleImageLayers& aLayers,
- const KTableEntry aTable[])
-{
- RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
-
- for (uint32_t i = 0, i_end = aLayers.*aCount; i < i_end; ++i) {
- RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
- val->SetIdent(nsCSSProps::ValueToKeywordEnum(aLayers.mLayers[i].*aMember,
- aTable));
- valueList->AppendCSSValue(val.forget());
- }
-
- return valueList.forget();
-}
-
-already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetBackgroundAttachment()
{
return GetBackgroundList(&nsStyleImageLayers::Layer::mAttachment,
@@ -2367,7 +2373,7 @@ nsComputedDOMStyle::DoGetBackgroundOrigin()
return GetBackgroundList(&nsStyleImageLayers::Layer::mOrigin,
&nsStyleImageLayers::mOriginCount,
StyleBackground()->mImage,
- nsCSSProps::kImageLayerOriginKTable);
+ nsCSSProps::kBackgroundOriginKTable);
}
void
@@ -5013,12 +5019,6 @@ nsComputedDOMStyle::DoGetTop()
return GetOffsetWidthFor(NS_SIDE_TOP);
}
-nsDOMCSSValueList*
-nsComputedDOMStyle::GetROCSSValueList(bool aCommaDelimited)
-{
- return new nsDOMCSSValueList(aCommaDelimited, true);
-}
-
already_AddRefed<CSSValue>
nsComputedDOMStyle::GetOffsetWidthFor(mozilla::css::Side aSide)
{
@@ -6180,8 +6180,8 @@ nsComputedDOMStyle::DoGetMask()
// need to support computed style for the cases where it used to be
// a longhand.
if (svg->mMask.mImageCount > 1 ||
- firstLayer.mClip != NS_STYLE_IMAGELAYER_CLIP_BORDER ||
- firstLayer.mOrigin != NS_STYLE_IMAGELAYER_ORIGIN_BORDER ||
+ firstLayer.mClip != StyleGeometryBox::Border ||
+ firstLayer.mOrigin != StyleGeometryBox::Border ||
firstLayer.mComposite != NS_STYLE_MASK_COMPOSITE_ADD ||
firstLayer.mMaskMode != NS_STYLE_MASK_MODE_MATCH_SOURCE ||
!nsStyleImageLayers::IsInitialPositionForLayerType(
@@ -6200,14 +6200,13 @@ nsComputedDOMStyle::DoGetMask()
return val.forget();
}
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetMaskClip()
{
return GetBackgroundList(&nsStyleImageLayers::Layer::mClip,
&nsStyleImageLayers::mClipCount,
StyleSVGReset()->mMask,
- nsCSSProps::kImageLayerOriginKTable);
+ nsCSSProps::kMaskClipKTable);
}
already_AddRefed<CSSValue>
@@ -6241,7 +6240,7 @@ nsComputedDOMStyle::DoGetMaskOrigin()
return GetBackgroundList(&nsStyleImageLayers::Layer::mOrigin,
&nsStyleImageLayers::mOriginCount,
StyleSVGReset()->mMask,
- nsCSSProps::kImageLayerOriginKTable);
+ nsCSSProps::kMaskOriginKTable);
}
already_AddRefed<CSSValue>
@@ -6278,7 +6277,6 @@ nsComputedDOMStyle::DoGetMaskSize()
const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
return DoGetImageLayerSize(layers);
}
-#endif
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetMaskType()
diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h
index 27e2086e92..77df71ec89 100644
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -53,6 +53,7 @@ private:
// Convenience typedefs:
typedef nsCSSProps::KTableEntry KTableEntry;
typedef mozilla::dom::CSSValue CSSValue;
+ typedef mozilla::StyleGeometryBox StyleGeometryBox;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -202,12 +203,6 @@ private:
const nscolor& aDefaultColor,
bool aIsBoxShadow);
- already_AddRefed<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,
@@ -310,7 +305,6 @@ private:
/* Mask properties */
already_AddRefed<CSSValue> DoGetMask();
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
already_AddRefed<CSSValue> DoGetMaskImage();
already_AddRefed<CSSValue> DoGetMaskPosition();
already_AddRefed<CSSValue> DoGetMaskPositionX();
@@ -321,7 +315,7 @@ private:
already_AddRefed<CSSValue> DoGetMaskSize();
already_AddRefed<CSSValue> DoGetMaskMode();
already_AddRefed<CSSValue> DoGetMaskComposite();
-#endif
+
/* Padding properties */
already_AddRefed<CSSValue> DoGetPaddingTop();
already_AddRefed<CSSValue> DoGetPaddingBottom();
@@ -582,8 +576,6 @@ private:
/* Custom properties */
already_AddRefed<CSSValue> DoGetCustomProperty(const nsAString& aPropertyName);
- nsDOMCSSValueList* GetROCSSValueList(bool aCommaDelimited);
-
/* Helper functions */
void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
void SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue,
diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h
index 1983208acc..825976b583 100644
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -332,7 +332,6 @@ COMPUTED_STYLE_PROP(marker_end, MarkerEnd)
COMPUTED_STYLE_PROP(marker_mid, MarkerMid)
COMPUTED_STYLE_PROP(marker_start, MarkerStart)
COMPUTED_STYLE_PROP(mask, Mask)
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
COMPUTED_STYLE_PROP(mask_clip, MaskClip)
COMPUTED_STYLE_PROP(mask_composite, MaskComposite)
COMPUTED_STYLE_PROP(mask_image, MaskImage)
@@ -343,7 +342,6 @@ COMPUTED_STYLE_PROP(mask_position_x, MaskPositionX)
COMPUTED_STYLE_PROP(mask_position_y, MaskPositionY)
COMPUTED_STYLE_PROP(mask_repeat, MaskRepeat)
COMPUTED_STYLE_PROP(mask_size, MaskSize)
-#endif
COMPUTED_STYLE_PROP(mask_type, MaskType)
COMPUTED_STYLE_PROP(paint_order, PaintOrder)
COMPUTED_STYLE_PROP(shape_rendering, ShapeRendering)
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 9b9fc3948e..6bcef02a05 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -22,6 +22,7 @@
#include "mozilla/Unused.h"
#include "mozilla/css/Declaration.h"
+#include "mozilla/TypeTraits.h"
#include "nsAlgorithm.h" // for clamped()
#include "nsRuleNode.h"
@@ -6800,6 +6801,21 @@ struct BackgroundItemComputer<nsCSSValueList, RefPtr<css::URLValueData>>
}
};
+template <typename T>
+struct BackgroundItemComputer<nsCSSValueList, T>
+{
+ typedef typename EnableIf<IsEnum<T>::value, T>::Type ComputedType;
+
+ static void ComputeValue(nsStyleContext* aStyleContext,
+ const nsCSSValueList* aSpecifiedValue,
+ ComputedType& aComputedValue,
+ RuleNodeCacheConditions& aConditions)
+ {
+ aComputedValue =
+ static_cast<T>(aSpecifiedValue->mValue.GetIntValue());
+ }
+};
+
/* Helper function for ComputePositionValue.
* This function computes a single PositionCoord from two nsCSSValue objects,
* which represent an edge and an offset from that edge.
@@ -7353,7 +7369,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
bg->mImage.mLayers,
parentBG->mImage.mLayers,
&nsStyleImageLayers::Layer::mClip,
- uint8_t(NS_STYLE_IMAGELAYER_CLIP_BORDER),
+ StyleGeometryBox::Border,
parentBG->mImage.mClipCount,
bg->mImage.mClipCount, maxItemCount, rebuild, conditions);
@@ -7372,7 +7388,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
bg->mImage.mLayers,
parentBG->mImage.mLayers,
&nsStyleImageLayers::Layer::mOrigin,
- uint8_t(NS_STYLE_IMAGELAYER_ORIGIN_PADDING),
+ StyleGeometryBox::Padding,
parentBG->mImage.mOriginCount,
bg->mImage.mOriginCount, maxItemCount, rebuild,
conditions);
@@ -10005,7 +10021,6 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
parentSVGReset->mMaskType,
NS_STYLE_MASK_TYPE_LUMINANCE);
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
uint32_t maxItemCount = 1;
bool rebuild = false;
@@ -10043,7 +10058,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
svgReset->mMask.mLayers,
parentSVGReset->mMask.mLayers,
&nsStyleImageLayers::Layer::mClip,
- uint8_t(NS_STYLE_IMAGELAYER_CLIP_BORDER),
+ StyleGeometryBox::Border,
parentSVGReset->mMask.mClipCount,
svgReset->mMask.mClipCount, maxItemCount, rebuild,
conditions);
@@ -10053,7 +10068,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
svgReset->mMask.mLayers,
parentSVGReset->mMask.mLayers,
&nsStyleImageLayers::Layer::mOrigin,
- uint8_t(NS_STYLE_IMAGELAYER_ORIGIN_BORDER),
+ StyleGeometryBox::Border,
parentSVGReset->mMask.mOriginCount,
svgReset->mMask.mOriginCount, maxItemCount, rebuild,
conditions);
@@ -10113,21 +10128,6 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
if (rebuild) {
FillAllBackgroundLists(svgReset->mMask, maxItemCount);
}
-#else
- // mask: none | <url>
- const nsCSSValue* maskValue = aRuleData->ValueForMask();
- if (eCSSUnit_URL == maskValue->GetUnit()) {
- svgReset->mMask.mLayers[0].mSourceURI = maskValue->GetURLStructValue();
- } else if (eCSSUnit_None == maskValue->GetUnit() ||
- eCSSUnit_Initial == maskValue->GetUnit() ||
- eCSSUnit_Unset == maskValue->GetUnit()) {
- svgReset->mMask.mLayers[0].mSourceURI = nullptr;
- } else if (eCSSUnit_Inherit == maskValue->GetUnit()) {
- conditions.SetUncacheable();
- svgReset->mMask.mLayers[0].mSourceURI =
- parentSVGReset->mMask.mLayers[0].mSourceURI;
- }
-#endif
COMPUTE_END_RESET(SVGReset, svgReset)
}
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index be588113e9..6d207aec9b 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -134,16 +134,35 @@ enum class StyleClear : uint8_t {
Max = 13 // Max = (Both | Line)
};
-// clip-path geometry box
-enum class StyleClipPathGeometryBox : uint8_t {
- NoBox,
+// Define geometry box for clip-path's reference-box, background-clip,
+// background-origin, mask-clip and mask-origin.
+enum class StyleGeometryBox : uint8_t {
Content,
Padding,
Border,
- Margin,
- Fill,
- Stroke,
- View,
+ Margin, // XXX Bug 1260094 comment 9.
+ // Although margin-box is required by mask-origin and mask-clip, we
+ // do not implement that due to lack of support in other browsers.
+ // clip-path reference-box only.
+ Fill, // mask-clip, mask-origin and clip-path reference-box only.
+ Stroke, // mask-clip, mask-origin and clip-path reference-box only.
+ View, // mask-clip, mask-origin and clip-path reference-box only.
+ NoClip, // mask-clip only.
+ Text, // background-clip only.
+ NoBox, // Depending on which kind of element this style value applied on,
+ // the default value of a reference-box can be different.
+ // For an HTML element, the default value of reference-box is
+ // border-box; for an SVG element, the default value is fill-box.
+ // Since we can not determine the default value at parsing time,
+ // set it as NoBox so that we make a decision later.
+ // clip-path reference-box only.
+ MozAlmostPadding = 127 // A magic value that we use for our "pretend that
+ // background-clip is 'padding' when we have a solid
+ // border" optimization. This isn't actually equal
+ // to StyleGeometryBox::Padding because using that
+ // causes antialiasing seams between the background
+ // and border.
+ // background-clip only.
};
// fill-rule
@@ -359,14 +378,6 @@ enum class FillMode : uint32_t;
#define NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED 1
#define NS_STYLE_IMAGELAYER_ATTACHMENT_LOCAL 2
-// See nsStyleImageLayers
-// Code depends on these constants having the same values as IMAGELAYER_ORIGIN_*
-#define NS_STYLE_IMAGELAYER_CLIP_BORDER 0
-#define NS_STYLE_IMAGELAYER_CLIP_PADDING 1
-#define NS_STYLE_IMAGELAYER_CLIP_CONTENT 2
-// One extra constant which does not exist in IMAGELAYER_ORIGIN_*
-#define NS_STYLE_IMAGELAYER_CLIP_TEXT 3
-
// A magic value that we use for our "pretend that background-clip is
// 'padding' when we have a solid border" optimization. This isn't
// actually equal to NS_STYLE_IMAGELAYER_CLIP_PADDING because using that
@@ -375,12 +386,6 @@ enum class FillMode : uint32_t;
#define NS_STYLE_IMAGELAYER_CLIP_MOZ_ALMOST_PADDING 127
// See nsStyleImageLayers
-// Code depends on these constants having the same values as BG_CLIP_*
-#define NS_STYLE_IMAGELAYER_ORIGIN_BORDER 0
-#define NS_STYLE_IMAGELAYER_ORIGIN_PADDING 1
-#define NS_STYLE_IMAGELAYER_ORIGIN_CONTENT 2
-
-// See nsStyleImageLayers
// The parser code depends on |ing these values together.
#define NS_STYLE_IMAGELAYER_POSITION_CENTER (1<<0)
#define NS_STYLE_IMAGELAYER_POSITION_TOP (1<<1)
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index 52491a288a..72c1037243 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2465,7 +2465,6 @@ const nsCSSPropertyID nsStyleImageLayers::kBackgroundLayerTable[] = {
eCSSProperty_UNKNOWN // composite
};
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
const nsCSSPropertyID nsStyleImageLayers::kMaskLayerTable[] = {
eCSSProperty_mask, // shorthand
eCSSProperty_UNKNOWN, // color
@@ -2480,7 +2479,6 @@ const nsCSSPropertyID nsStyleImageLayers::kMaskLayerTable[] = {
eCSSProperty_mask_mode, // maskMode
eCSSProperty_mask_composite // composite
};
-#endif
nsStyleImageLayers::nsStyleImageLayers(nsStyleImageLayers::LayerType aType)
: mAttachmentCount(1)
@@ -2787,7 +2785,7 @@ nsStyleImageLayers::Size::operator==(const Size& aOther) const
}
nsStyleImageLayers::Layer::Layer()
- : mClip(NS_STYLE_IMAGELAYER_CLIP_BORDER)
+ : mClip(StyleGeometryBox::Border)
, mAttachment(NS_STYLE_IMAGELAYER_ATTACHMENT_SCROLL)
, mBlendMode(NS_STYLE_BLEND_NORMAL)
, mComposite(NS_STYLE_MASK_COMPOSITE_ADD)
@@ -2809,10 +2807,10 @@ nsStyleImageLayers::Layer::Initialize(nsStyleImageLayers::LayerType aType)
mPosition.SetInitialPercentValues(0.0f);
if (aType == LayerType::Background) {
- mOrigin = NS_STYLE_IMAGELAYER_ORIGIN_PADDING;
+ mOrigin = StyleGeometryBox::Padding;
} else {
MOZ_ASSERT(aType == LayerType::Mask, "unsupported layer type.");
- mOrigin = NS_STYLE_IMAGELAYER_ORIGIN_BORDER;
+ mOrigin = StyleGeometryBox::Border;
}
}
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 1cadea8406..c8182b8f14 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -782,6 +782,8 @@ struct nsStyleImageLayers {
struct Layer;
friend struct Layer;
struct Layer {
+ typedef mozilla::StyleGeometryBox StyleGeometryBox;
+
nsStyleImage mImage; // [reset]
RefPtr<mozilla::css::URLValueData> mSourceURI; // [reset]
// mask-only property
@@ -793,9 +795,9 @@ struct nsStyleImageLayers {
// or an ImageValue.)
mozilla::Position mPosition; // [reset]
Size mSize; // [reset]
- uint8_t mClip; // [reset] See nsStyleConsts.h
+ StyleGeometryBox mClip; // [reset] See nsStyleConsts.h
MOZ_INIT_OUTSIDE_CTOR
- uint8_t mOrigin; // [reset] See nsStyleConsts.h
+ StyleGeometryBox mOrigin; // [reset] See nsStyleConsts.h
uint8_t mAttachment; // [reset] See nsStyleConsts.h
// background-only property
// This property is used for background layer
@@ -2755,7 +2757,7 @@ private:
ReferenceBox mReferenceBox = ReferenceBox::NoBox;
};
-using StyleClipPath = StyleShapeSource<StyleClipPathGeometryBox>;
+using StyleClipPath = StyleShapeSource<StyleGeometryBox>;
using StyleShapeOutside = StyleShapeSource<StyleShapeOutsideShapeBox>;
} // namespace mozilla
diff --git a/layout/svg/nsCSSClipPathInstance.cpp b/layout/svg/nsCSSClipPathInstance.cpp
index 828b10eaca..01f7de248e 100644
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -62,122 +62,12 @@ nsCSSClipPathInstance::HitTestBasicShapeClip(nsIFrame* aFrame,
return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
}
-nsRect
-nsCSSClipPathInstance::ComputeSVGReferenceRect()
-{
- MOZ_ASSERT(mTargetFrame->GetContent()->IsSVGElement());
- nsRect r;
-
- // For SVG elements without associated CSS layout box, the used value for
- // content-box, padding-box, border-box and margin-box is fill-box.
- switch (mClipPathStyle.GetReferenceBox()) {
- case StyleClipPathGeometryBox::Stroke: {
- // XXX Bug 1299876
- // The size of srtoke-box is not correct if this graphic element has
- // specific stroke-linejoin or stroke-linecap.
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIncludeStroke);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- case StyleClipPathGeometryBox::View: {
- nsIContent* content = mTargetFrame->GetContent();
- nsSVGElement* element = static_cast<nsSVGElement*>(content);
- SVGSVGElement* svgElement = element->GetCtx();
- MOZ_ASSERT(svgElement);
-
- if (svgElement && svgElement->HasViewBoxRect()) {
- // If a ‘viewBox‘ attribute is specified for the SVG viewport creating
- // element:
- // 1. The reference box is positioned at the origin of the coordinate
- // system established by the ‘viewBox‘ attribute.
- // 2. The dimension of the reference box is set to the width and height
- // values of the ‘viewBox‘ attribute.
- nsSVGViewBox* viewBox = svgElement->GetViewBox();
- const nsSVGViewBoxRect& value = viewBox->GetAnimValue();
- r = nsRect(nsPresContext::CSSPixelsToAppUnits(value.x),
- nsPresContext::CSSPixelsToAppUnits(value.y),
- nsPresContext::CSSPixelsToAppUnits(value.width),
- nsPresContext::CSSPixelsToAppUnits(value.height));
- } else {
- // No viewBox is specified, uses the nearest SVG viewport as reference
- // box.
- svgFloatSize viewportSize = svgElement->GetViewportSize();
- r = nsRect(0, 0,
- nsPresContext::CSSPixelsToAppUnits(viewportSize.width),
- nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
- }
-
- break;
- }
- case StyleClipPathGeometryBox::NoBox:
- case StyleClipPathGeometryBox::Border:
- case StyleClipPathGeometryBox::Content:
- case StyleClipPathGeometryBox::Padding:
- case StyleClipPathGeometryBox::Margin:
- case StyleClipPathGeometryBox::Fill: {
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- default:{
- MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
- gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
- nsSVGUtils::eBBoxIncludeFill);
- r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
- nsPresContext::AppUnitsPerCSSPixel());
- break;
- }
- }
-
- return r;
-}
-
-nsRect
-nsCSSClipPathInstance::ComputeHTMLReferenceRect()
-{
- nsRect r;
-
- // For elements with associated CSS layout box, the used value for fill-box,
- // stroke-box and view-box is border-box.
- switch (mClipPathStyle.GetReferenceBox()) {
- case StyleClipPathGeometryBox::Content:
- r = mTargetFrame->GetContentRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::Padding:
- r = mTargetFrame->GetPaddingRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::Margin:
- r = mTargetFrame->GetMarginRectRelativeToSelf();
- break;
- case StyleClipPathGeometryBox::NoBox:
- case StyleClipPathGeometryBox::Border:
- case StyleClipPathGeometryBox::Fill:
- case StyleClipPathGeometryBox::Stroke:
- case StyleClipPathGeometryBox::View:
- r = mTargetFrame->GetRectRelativeToSelf();
- break;
- default:
- MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
- r = mTargetFrame->GetRectRelativeToSelf();
- break;
- }
-
- return r;
-}
-
already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
{
- // We use ComputeSVGReferenceRect for all SVG elements, except <svg>
- // element, which does have an associated CSS layout box. In this case we
- // should still use ComputeHTMLReferenceRect for region computing.
- nsRect r = mTargetFrame->IsFrameOfType(nsIFrame::eSVG) &&
- (mTargetFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)
- ? ComputeSVGReferenceRect() : ComputeHTMLReferenceRect();
+ nsRect r =
+ nsLayoutUtils::ComputeGeometryBox(mTargetFrame,
+ mClipPathStyle.GetReferenceBox());
if (mClipPathStyle.GetType() != StyleShapeSourceType::Shape) {
// TODO Clip to border-radius/reference box if no shape
diff --git a/layout/svg/nsCSSClipPathInstance.h b/layout/svg/nsCSSClipPathInstance.h
index 3b0724dbd0..33d92e738e 100644
--- a/layout/svg/nsCSSClipPathInstance.h
+++ b/layout/svg/nsCSSClipPathInstance.h
@@ -48,10 +48,6 @@ private:
already_AddRefed<Path> CreateClipPathInset(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
-
- nsRect ComputeHTMLReferenceRect();
- nsRect ComputeSVGReferenceRect();
-
/**
* The frame for the element that is currently being clipped.
*/
diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp
index 498f693937..0003e1a73e 100644
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -509,71 +509,108 @@ PaintMaskSurface(const PaintFramesParams& aParams,
return DrawResult::SUCCESS;
}
-static DrawResult
+struct MaskPaintResult {
+ RefPtr<SourceSurface> maskSurface;
+ Matrix maskTransform;
+ DrawResult result;
+ bool transparentBlackMask;
+ bool opacityApplied;
+
+ MaskPaintResult()
+ : result(DrawResult::SUCCESS), transparentBlackMask(false),
+ opacityApplied(false)
+ {}
+};
+
+static MaskPaintResult
CreateAndPaintMaskSurface(const PaintFramesParams& aParams,
float aOpacity, nsStyleContext* aSC,
const nsTArray<nsSVGMaskFrame*>& aMaskFrames,
- const nsPoint& aOffsetToUserSpace,
- Matrix& aOutMaskTransform,
- RefPtr<SourceSurface>& aOutMaskSurface,
- bool& aOpacityApplied)
+ const nsPoint& aOffsetToUserSpace)
{
const nsStyleSVGReset *svgReset = aSC->StyleSVGReset();
MOZ_ASSERT(aMaskFrames.Length() > 0);
+ MaskPaintResult paintResult;
gfxContext& ctx = aParams.ctx;
- // There is only one SVG mask.
+ // Optimization for single SVG mask.
if (((aMaskFrames.Length() == 1) && aMaskFrames[0])) {
gfxMatrix cssPxToDevPxMatrix =
nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aParams.frame);
+ paintResult.opacityApplied = true;
- aOpacityApplied = true;
- aOutMaskSurface =
+ paintResult.maskSurface =
aMaskFrames[0]->GetMaskForMaskedFrame(&ctx, aParams.frame,
cssPxToDevPxMatrix, aOpacity,
- &aOutMaskTransform,
+ &paintResult.maskTransform,
svgReset->mMask.mLayers[0].mMaskMode);
- return DrawResult::SUCCESS;
+ if (!paintResult.maskSurface) {
+ paintResult.transparentBlackMask = true;
+ }
+
+ return paintResult;
}
const IntRect& maskSurfaceRect = aParams.maskRect;
if (maskSurfaceRect.IsEmpty()) {
- return DrawResult::SUCCESS;
+ paintResult.transparentBlackMask = true;
+ return paintResult;
}
RefPtr<DrawTarget> maskDT =
ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(),
SurfaceFormat::A8);
if (!maskDT || !maskDT->IsValid()) {
- return DrawResult::TEMPORARY_ERROR;
+ paintResult.result = DrawResult::TEMPORARY_ERROR;
+ return paintResult;
}
// Set aAppliedOpacity as true only if all mask layers are svg mask.
// In this case, we will apply opacity into the final mask surface, so the
// caller does not need to apply it again.
- aOpacityApplied = !HasNonSVGMask(aMaskFrames);
+ paintResult.opacityApplied = !HasNonSVGMask(aMaskFrames);
// Set context's matrix on maskContext, offset by the maskSurfaceRect's
// position. This makes sure that we combine the masks in device space.
gfxMatrix maskSurfaceMatrix =
ctx.CurrentMatrix() * gfxMatrix::Translation(-aParams.maskRect.TopLeft());
- DrawResult result = PaintMaskSurface(aParams, maskDT,
- aOpacityApplied ? aOpacity : 1.0,
- aSC, aMaskFrames, maskSurfaceMatrix,
- aOffsetToUserSpace);
- if (result != DrawResult::SUCCESS) {
- return result;
- }
-
- aOutMaskTransform = ToMatrix(maskSurfaceMatrix);
- if (!aOutMaskTransform.Invert()) {
- return DrawResult::SUCCESS;
+ paintResult.result = PaintMaskSurface(aParams, maskDT,
+ paintResult.opacityApplied
+ ? aOpacity : 1.0,
+ aSC, aMaskFrames, maskSurfaceMatrix,
+ aOffsetToUserSpace);
+ if (paintResult.result != DrawResult::SUCCESS) {
+ // Now we know the status of mask resource since we used it while painting.
+ // According to the return value of PaintMaskSurface, we know whether mask
+ // resource is resolvable or not.
+ //
+ // For a HTML doc:
+ // According to css-masking spec, always create a mask surface when
+ // we have any item in maskFrame even if all of those items are
+ // non-resolvable <mask-sources> or <images>.
+ // Set paintResult.transparentBlackMask as true, the caller should stop
+ // painting masked content as if this mask is a transparent black one.
+ // For a SVG doc:
+ // SVG 1.1 say that if we fail to resolve a mask, we should draw the
+ // object unmasked.
+ // Left patinResult.maskSurface empty, the caller should paint all
+ // masked content as if this mask is an opaque white one(no mask).
+ paintResult.transparentBlackMask =
+ !(aParams.frame->GetStateBits() & NS_FRAME_SVG_LAYOUT);
+
+ MOZ_ASSERT(!paintResult.maskSurface);
+ return paintResult;
+ }
+
+ paintResult.maskTransform = ToMatrix(maskSurfaceMatrix);
+ if (!paintResult.maskTransform.Invert()) {
+ return paintResult;
}
- aOutMaskSurface = maskDT->Snapshot();
- return DrawResult::SUCCESS;
+ paintResult.maskSurface = maskDT->Snapshot();
+ return paintResult;
}
static bool
@@ -783,6 +820,8 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
maskUsage.shouldGenerateClipMaskLayer ||
maskUsage.shouldGenerateMaskLayer);
+ bool shouldPushMask = false;
+
/* Check if we need to do additional operations on this child's
* rendering, which necessitates rendering into another surface. */
if (shouldGenerateMask) {
@@ -800,14 +839,23 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
// instead of the first continuation frame.
SetupContextMatrix(frame, aParams, offsetToBoundingBox,
offsetToUserSpace);
- result = CreateAndPaintMaskSurface(aParams, maskUsage.opacity,
- firstFrame->StyleContext(),
- maskFrames, offsetToUserSpace,
- maskTransform, maskSurface,
- opacityApplied);
- if (!maskSurface) {
- // Entire surface is clipped out.
- return result;
+ MaskPaintResult paintResult =
+ CreateAndPaintMaskSurface(aParams, maskUsage.opacity,
+ firstFrame->StyleContext(),
+ maskFrames, offsetToUserSpace);
+
+ if (paintResult.transparentBlackMask) {
+ MOZ_ASSERT(paintResult.result != DrawResult::SUCCESS);
+ return paintResult.result;
+ }
+
+ result &= paintResult.result;
+ maskSurface = paintResult.maskSurface;
+ if (maskSurface) {
+ MOZ_ASSERT(paintResult.result == DrawResult::SUCCESS);
+ shouldPushMask = true;
+ maskTransform = paintResult.maskTransform;
+ opacityApplied = paintResult.opacityApplied;
}
}
@@ -831,6 +879,8 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
// failure in nsSVGClipPathFrame::GetClipMask.
return result;
}
+
+ shouldPushMask = true;
}
// opacity != 1.0f.
@@ -841,18 +891,22 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
matSR.SetContext(&context);
SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
offsetToUserSpace);
+ shouldPushMask = true;
}
- if (aParams.layerManager->GetRoot()->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
- context.PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA,
- opacityApplied
- ? 1.0
- : maskUsage.opacity,
- maskSurface, maskTransform);
- } else {
- context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
- opacityApplied ? 1.0 : maskUsage.opacity,
- maskSurface, maskTransform);
+ if (shouldPushMask) {
+ if (aParams.layerManager->GetRoot()->GetContentFlags() &
+ Layer::CONTENT_COMPONENT_ALPHA) {
+ context.PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA,
+ opacityApplied
+ ? 1.0
+ : maskUsage.opacity,
+ maskSurface, maskTransform);
+ } else {
+ context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
+ opacityApplied ? 1.0 : maskUsage.opacity,
+ maskSurface, maskTransform);
+ }
}
}
@@ -899,7 +953,7 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
context.PopClip();
}
- if (shouldGenerateMask) {
+ if (shouldPushMask) {
context.PopGroupAndBlend();
}
diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp
index 344ebf645a..0bded21ffe 100644
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -514,26 +514,7 @@ nsSVGUtils::DetermineMaskUsage(nsIFrame* aFrame, bool aHandleOpacity,
nsTArray<nsSVGMaskFrame*> maskFrames = effectProperties.GetMaskFrames();
-#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
- // For a HTML doc:
- // According to css-masking spec, always create a mask surface when we
- // have any item in maskFrame even if all of those items are
- // non-resolvable <mask-sources> or <images>, we still need to create a
- // transparent black mask layer under this condition.
- // For a SVG doc:
- // SVG 1.1 say that if we fail to resolve a mask, we should draw the
- // object unmasked.
- aUsage.shouldGenerateMaskLayer =
- (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)
- ? maskFrames.Length() == 1 && maskFrames[0]
- : maskFrames.Length() > 0;
-#else
- // Since we do not support image mask so far, we should treat any
- // unresolvable mask as no mask. Otherwise, any object with a valid image
- // mask, e.g. url("xxx.png"), will become invisible just because we can not
- // handle image mask correctly. (See bug 1294171)
- aUsage.shouldGenerateMaskLayer = maskFrames.Length() == 1 && maskFrames[0];
-#endif
+ aUsage.shouldGenerateMaskLayer = (maskFrames.Length() > 0);
bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);