mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
Bug 1852323 - Part 2: Fix the mapping of StyleGeometryBox for mask-clip. r=emilio
Also, drop `nsLayoutUtils::ComputeGeometryBox()` and avoid doing mapping in `ComputeHTMLReferenceRect()` and `ComputeSVGReferenceRect()`. The caller should handle it properly because each property uses its own mapping between CSS box and SVG box. Note: 1. mask-clip-3.html is copied from mask-clip-1.html but just replace css boxes with svg boxes. 2. mask-clip-4.html is copied from mask-clip-2.html but just replace svg boxed with css boxes. Differential Revision: https://phabricator.services.mozilla.com/D188316
This commit is contained in:
parent
5213031e3e
commit
192403f967
@ -39,13 +39,34 @@ CSSPoint MotionPathUtils::ComputeAnchorPointAdjustment(const nsIFrame& aFrame) {
|
||||
}
|
||||
|
||||
if (aFrame.IsFrameOfType(nsIFrame::eSVGContainer)) {
|
||||
nsRect boxRect = nsLayoutUtils::ComputeGeometryBox(
|
||||
nsRect boxRect = nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
const_cast<nsIFrame*>(&aFrame), StyleGeometryBox::FillBox);
|
||||
return CSSPoint::FromAppUnits(boxRect.TopLeft());
|
||||
}
|
||||
return CSSPoint::FromAppUnits(aFrame.GetPosition());
|
||||
}
|
||||
|
||||
// Convert the StyleCoordBox into the StyleGeometryBox in CSS layout.
|
||||
// https://drafts.csswg.org/css-box-4/#keywords
|
||||
static StyleGeometryBox CoordBoxToGeometryBoxInCSSLayout(
|
||||
StyleCoordBox aCoordBox) {
|
||||
switch (aCoordBox) {
|
||||
case StyleCoordBox::ContentBox:
|
||||
return StyleGeometryBox::ContentBox;
|
||||
case StyleCoordBox::PaddingBox:
|
||||
return StyleGeometryBox::PaddingBox;
|
||||
case StyleCoordBox::BorderBox:
|
||||
return StyleGeometryBox::BorderBox;
|
||||
case StyleCoordBox::FillBox:
|
||||
return StyleGeometryBox::ContentBox;
|
||||
case StyleCoordBox::StrokeBox:
|
||||
case StyleCoordBox::ViewBox:
|
||||
return StyleGeometryBox::BorderBox;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown coord-box type");
|
||||
return StyleGeometryBox::BorderBox;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const nsIFrame* MotionPathUtils::GetOffsetPathReferenceBox(
|
||||
const nsIFrame* aFrame, nsRect& aOutputRect) {
|
||||
@ -67,7 +88,7 @@ const nsIFrame* MotionPathUtils::GetOffsetPathReferenceBox(
|
||||
? offsetPath.AsCoordBox()
|
||||
: offsetPath.AsOffsetPath().coord_box;
|
||||
aOutputRect = nsLayoutUtils::ComputeHTMLReferenceRect(
|
||||
containingBlock, nsLayoutUtils::CoordBoxToGeometryBox(coordBox));
|
||||
containingBlock, CoordBoxToGeometryBoxInCSSLayout(coordBox));
|
||||
return containingBlock;
|
||||
}
|
||||
|
||||
@ -78,15 +99,14 @@ CSSCoord MotionPathUtils::GetRayContainReferenceSize(nsIFrame* aFrame) {
|
||||
// https://drafts.fxtf.org/motion-1/#valdef-ray-contain
|
||||
//
|
||||
// Note: Per the spec, border-box is treated as stroke-box in the SVG context,
|
||||
// Also, SVGUtils::GetBBox() may cache the box via the frame property, so we
|
||||
// have to do const-casting.
|
||||
// https://drafts.csswg.org/css-box-4/#valdef-box-border-box
|
||||
CSSSize size = CSSSize::FromAppUnits(
|
||||
nsLayoutUtils::ComputeGeometryBox(aFrame,
|
||||
// StrokeBox and BorderBox are in the
|
||||
// same switch case for CSS context.
|
||||
StyleGeometryBox::StrokeBox)
|
||||
.Size());
|
||||
const auto size =
|
||||
CSSSize::FromAppUnits((aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)
|
||||
? nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
aFrame, StyleGeometryBox::StrokeBox)
|
||||
: nsLayoutUtils::ComputeHTMLReferenceRect(
|
||||
aFrame, StyleGeometryBox::BorderBox))
|
||||
.Size());
|
||||
return std::max(size.width, size.height);
|
||||
}
|
||||
|
||||
|
@ -9603,18 +9603,13 @@ nsRect nsLayoutUtils::ComputeSVGOriginBox(SVGViewportElement* aElement) {
|
||||
nsPresContext::CSSPixelsToAppUnits(viewportSize.height));
|
||||
}
|
||||
|
||||
static nsRect ComputeSVGReferenceRect(nsIFrame* aFrame,
|
||||
StyleGeometryBox aGeometryBox) {
|
||||
/* static */
|
||||
nsRect nsLayoutUtils::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 and padding-box is fill-box and for
|
||||
// border-box and margin-box is stroke-box.
|
||||
switch (aGeometryBox) {
|
||||
case StyleGeometryBox::NoBox:
|
||||
case StyleGeometryBox::BorderBox:
|
||||
case StyleGeometryBox::MarginBox:
|
||||
case StyleGeometryBox::StrokeBox: {
|
||||
// XXX Bug 1299876
|
||||
// The size of stroke-box is not correct if this graphic element has
|
||||
@ -9635,8 +9630,6 @@ static nsRect ComputeSVGReferenceRect(nsIFrame* aFrame,
|
||||
r = nsLayoutUtils::ComputeSVGOriginBox(viewportElement);
|
||||
break;
|
||||
}
|
||||
case StyleGeometryBox::ContentBox:
|
||||
case StyleGeometryBox::PaddingBox:
|
||||
case StyleGeometryBox::FillBox: {
|
||||
gfxRect bbox =
|
||||
SVGUtils::GetBBox(aFrame, SVGUtils::eBBoxIncludeFillGeometry);
|
||||
@ -9644,10 +9637,7 @@ static nsRect ComputeSVGReferenceRect(nsIFrame* aFrame,
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
MOZ_ASSERT_UNREACHABLE("unknown StyleGeometryBox type");
|
||||
gfxRect bbox =
|
||||
SVGUtils::GetBBox(aFrame, SVGUtils::eBBoxIncludeFillGeometry);
|
||||
r = nsLayoutUtils::RoundGfxRectToAppRect(bbox, AppUnitsPerCSSPixel());
|
||||
MOZ_ASSERT_UNREACHABLE("unsupported SVG box");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -9660,8 +9650,6 @@ nsRect nsLayoutUtils::ComputeHTMLReferenceRect(const 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::ContentBox:
|
||||
r = aFrame->GetContentRectRelativeToSelf();
|
||||
@ -9672,53 +9660,17 @@ nsRect nsLayoutUtils::ComputeHTMLReferenceRect(const nsIFrame* aFrame,
|
||||
case StyleGeometryBox::MarginBox:
|
||||
r = aFrame->GetMarginRectRelativeToSelf();
|
||||
break;
|
||||
case StyleGeometryBox::NoBox:
|
||||
case StyleGeometryBox::BorderBox:
|
||||
case StyleGeometryBox::FillBox:
|
||||
case StyleGeometryBox::StrokeBox:
|
||||
case StyleGeometryBox::ViewBox:
|
||||
r = aFrame->GetRectRelativeToSelf();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unknown StyleGeometryBox type");
|
||||
r = aFrame->GetRectRelativeToSelf();
|
||||
MOZ_ASSERT_UNREACHABLE("unsupported CSS box");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* static */
|
||||
StyleGeometryBox nsLayoutUtils::CoordBoxToGeometryBox(StyleCoordBox aCoordBox) {
|
||||
switch (aCoordBox) {
|
||||
case StyleCoordBox::ContentBox:
|
||||
return StyleGeometryBox::ContentBox;
|
||||
case StyleCoordBox::PaddingBox:
|
||||
return StyleGeometryBox::PaddingBox;
|
||||
case StyleCoordBox::BorderBox:
|
||||
return StyleGeometryBox::BorderBox;
|
||||
case StyleCoordBox::FillBox:
|
||||
return StyleGeometryBox::FillBox;
|
||||
case StyleCoordBox::StrokeBox:
|
||||
return StyleGeometryBox::StrokeBox;
|
||||
case StyleCoordBox::ViewBox:
|
||||
return StyleGeometryBox::ViewBox;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown coord-box type");
|
||||
return StyleGeometryBox::BorderBox;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
return aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)
|
||||
? ComputeSVGReferenceRect(aFrame, aGeometryBox)
|
||||
: ComputeHTMLReferenceRect(aFrame, aGeometryBox);
|
||||
}
|
||||
|
||||
static StyleGeometryBox ShapeBoxToGeometryBox(const StyleShapeBox& aBox) {
|
||||
switch (aBox) {
|
||||
case StyleShapeBox::BorderBox:
|
||||
|
@ -2958,12 +2958,14 @@ class nsLayoutUtils {
|
||||
|
||||
static nsRect ComputeSVGOriginBox(mozilla::dom::SVGViewportElement*);
|
||||
|
||||
// Compute the geometry box for SVG layout. The caller should map the CSS box
|
||||
// into the proper SVG box.
|
||||
static nsRect ComputeSVGReferenceRect(nsIFrame*, StyleGeometryBox);
|
||||
|
||||
// Compute the geometry box for CSS layout. The caller should map the SVG box
|
||||
// into the proper CSS box.
|
||||
static nsRect ComputeHTMLReferenceRect(const nsIFrame*, StyleGeometryBox);
|
||||
|
||||
static StyleGeometryBox CoordBoxToGeometryBox(mozilla::StyleCoordBox);
|
||||
|
||||
static nsRect ComputeGeometryBox(nsIFrame*, StyleGeometryBox);
|
||||
|
||||
static nsRect ComputeClipPathGeometryBox(
|
||||
nsIFrame*, const mozilla::StyleShapeGeometryBox&);
|
||||
|
||||
|
@ -2029,17 +2029,19 @@ static bool IsHTMLStyleGeometryBox(StyleGeometryBox aBox) {
|
||||
aBox == StyleGeometryBox::MarginBox);
|
||||
}
|
||||
|
||||
static StyleGeometryBox ComputeBoxValue(nsIFrame* aForFrame,
|
||||
StyleGeometryBox aBox) {
|
||||
static StyleGeometryBox ComputeBoxValueForOrigin(nsIFrame* aForFrame,
|
||||
StyleGeometryBox aBox) {
|
||||
// The mapping for mask-origin is from
|
||||
// https://drafts.fxtf.org/css-masking/#the-mask-origin
|
||||
if (!aForFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)) {
|
||||
// For elements with associated CSS layout box, the values fill-box,
|
||||
// stroke-box and view-box compute to the initial value of mask-clip.
|
||||
// stroke-box and view-box compute to the initial value of mask-origin.
|
||||
if (IsSVGStyleGeometryBox(aBox)) {
|
||||
return StyleGeometryBox::BorderBox;
|
||||
}
|
||||
} else {
|
||||
// For SVG elements without associated CSS layout box, the values
|
||||
// content-box, padding-box, border-box and margin-box compute to fill-box.
|
||||
// content-box, padding-box, border-box compute to fill-box.
|
||||
if (IsHTMLStyleGeometryBox(aBox)) {
|
||||
return StyleGeometryBox::FillBox;
|
||||
}
|
||||
@ -2048,6 +2050,40 @@ static StyleGeometryBox ComputeBoxValue(nsIFrame* aForFrame,
|
||||
return aBox;
|
||||
}
|
||||
|
||||
static StyleGeometryBox ComputeBoxValueForClip(const nsIFrame* aForFrame,
|
||||
StyleGeometryBox aBox) {
|
||||
// The mapping for mask-clip is from
|
||||
// https://drafts.fxtf.org/css-masking/#the-mask-clip
|
||||
if (aForFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)) {
|
||||
// For SVG elements without associated CSS layout box, the used values for
|
||||
// content-box and padding-box compute to fill-box and for border-box and
|
||||
// margin-box compute to stroke-box.
|
||||
switch (aBox) {
|
||||
case StyleGeometryBox::ContentBox:
|
||||
case StyleGeometryBox::PaddingBox:
|
||||
return StyleGeometryBox::FillBox;
|
||||
case StyleGeometryBox::BorderBox:
|
||||
case StyleGeometryBox::MarginBox:
|
||||
return StyleGeometryBox::StrokeBox;
|
||||
default:
|
||||
return aBox;
|
||||
}
|
||||
}
|
||||
|
||||
// For elements with associated CSS layout box, the used values for fill-box
|
||||
// compute to content-box and for stroke-box and view-box compute to
|
||||
// border-box.
|
||||
switch (aBox) {
|
||||
case StyleGeometryBox::FillBox:
|
||||
return StyleGeometryBox::ContentBox;
|
||||
case StyleGeometryBox::StrokeBox:
|
||||
case StyleGeometryBox::ViewBox:
|
||||
return StyleGeometryBox::BorderBox;
|
||||
default:
|
||||
return aBox;
|
||||
}
|
||||
}
|
||||
|
||||
bool nsCSSRendering::ImageLayerClipState::IsValid() const {
|
||||
// mDirtyRectInDevPx comes from mDirtyRectInAppUnits. mDirtyRectInAppUnits
|
||||
// can not be empty if mDirtyRectInDevPx is not.
|
||||
@ -2069,16 +2105,17 @@ void nsCSSRendering::GetImageLayerClip(
|
||||
const nsRect& aCallerDirtyRect, bool aWillPaintBorder,
|
||||
nscoord aAppUnitsPerPixel,
|
||||
/* out */ ImageLayerClipState* aClipState) {
|
||||
StyleGeometryBox layerClip = ComputeBoxValue(aForFrame, aLayer.mClip);
|
||||
StyleGeometryBox layerClip = ComputeBoxValueForClip(aForFrame, aLayer.mClip);
|
||||
if (IsSVGStyleGeometryBox(layerClip)) {
|
||||
MOZ_ASSERT(aForFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT));
|
||||
|
||||
// The coordinate space of clipArea is svg user space.
|
||||
nsRect clipArea = nsLayoutUtils::ComputeGeometryBox(aForFrame, layerClip);
|
||||
nsRect clipArea =
|
||||
nsLayoutUtils::ComputeSVGReferenceRect(aForFrame, layerClip);
|
||||
|
||||
nsRect strokeBox = (layerClip == StyleGeometryBox::StrokeBox)
|
||||
? clipArea
|
||||
: nsLayoutUtils::ComputeGeometryBox(
|
||||
: nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
aForFrame, StyleGeometryBox::StrokeBox);
|
||||
nsRect clipAreaRelativeToStrokeBox = clipArea - strokeBox.TopLeft();
|
||||
|
||||
@ -2708,17 +2745,19 @@ nsRect nsCSSRendering::ComputeImageLayerPositioningArea(
|
||||
// may need it to compute the effective image size for a CSS gradient.
|
||||
nsRect positionArea;
|
||||
|
||||
StyleGeometryBox layerOrigin = ComputeBoxValue(aForFrame, aLayer.mOrigin);
|
||||
StyleGeometryBox layerOrigin =
|
||||
ComputeBoxValueForOrigin(aForFrame, aLayer.mOrigin);
|
||||
|
||||
if (IsSVGStyleGeometryBox(layerOrigin)) {
|
||||
MOZ_ASSERT(aForFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT));
|
||||
*aAttachedToFrame = aForFrame;
|
||||
|
||||
positionArea = nsLayoutUtils::ComputeGeometryBox(aForFrame, layerOrigin);
|
||||
positionArea =
|
||||
nsLayoutUtils::ComputeSVGReferenceRect(aForFrame, layerOrigin);
|
||||
|
||||
nsPoint toStrokeBoxOffset = nsPoint(0, 0);
|
||||
if (layerOrigin != StyleGeometryBox::StrokeBox) {
|
||||
nsRect strokeBox = nsLayoutUtils::ComputeGeometryBox(
|
||||
nsRect strokeBox = nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
aForFrame, StyleGeometryBox::StrokeBox);
|
||||
toStrokeBoxOffset = positionArea.TopLeft() - strokeBox.TopLeft();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static nsRect GetSVGBox(const nsIFrame* aFrame) {
|
||||
case StyleTransformBox::FillBox: {
|
||||
// Percentages in transforms resolve against the SVG bbox, and the
|
||||
// transform is relative to the top-left of the SVG bbox.
|
||||
nsRect bboxInAppUnits = nsLayoutUtils::ComputeGeometryBox(
|
||||
nsRect bboxInAppUnits = nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
const_cast<nsIFrame*>(aFrame), StyleGeometryBox::FillBox);
|
||||
// The mRect of an SVG nsIFrame is its user space bounds *including*
|
||||
// stroke and markers, whereas bboxInAppUnits is its user space bounds
|
||||
@ -86,7 +86,7 @@ static nsRect GetSVGBox(const nsIFrame* aFrame) {
|
||||
// have simple bounds.
|
||||
// FIXME: Bug 1849054. We may have to update
|
||||
// SVGGeometryFrame::GetBBoxContribution() to get tighter stroke bounds.
|
||||
nsRect strokeBox = nsLayoutUtils::ComputeGeometryBox(
|
||||
nsRect strokeBox = nsLayoutUtils::ComputeSVGReferenceRect(
|
||||
const_cast<nsIFrame*>(aFrame), StyleGeometryBox::StrokeBox);
|
||||
// The |nsIFrame::mRect| includes markers, so we have to compute the
|
||||
// offsets without markers.
|
||||
|
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS mask-clip reference</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<style type="text/css">
|
||||
div {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
div.border {
|
||||
left: 10px;
|
||||
margin: 1px 4px;
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
div.border2 {
|
||||
left: 110px;
|
||||
margin: 1px 4px;
|
||||
width: 60px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
div.content {
|
||||
left: 210px;
|
||||
margin: 15px 13px;
|
||||
width: 40px;
|
||||
height: 11px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="color border"></div>
|
||||
<div class="color border2"></div>
|
||||
<div class="color content"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Masking: mask-clip: clip mask image</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#the-mask-clip">
|
||||
<link rel="match" href="mask-clip-3-ref.html">
|
||||
<meta name="assert" content="fill-box, stroke-box, view-box of mask-clip should clip to the appropriate boxes.">
|
||||
<style type="text/css">
|
||||
div.outer {
|
||||
/*
|
||||
* content box: 40 x 20
|
||||
* padding box: 52 x 38
|
||||
* border box: 60 x 50
|
||||
* margin box: 66 x 54
|
||||
*/
|
||||
background-color: purple;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
margin: 1px 2px 3px 4px;
|
||||
border: solid transparent;
|
||||
border-width: 8px 2px 4px 6px;
|
||||
padding: 6px 9px 12px 3px;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
div.mask {
|
||||
mask-size: 100% 100%;
|
||||
mask-origin: border-box;
|
||||
mask-image: url(support/transparent-100x50-blue-100x50.svg);
|
||||
}
|
||||
|
||||
div.stroke {
|
||||
left: 10px;
|
||||
mask-clip: stroke-box; /* should be the same as border-box */
|
||||
}
|
||||
|
||||
div.view {
|
||||
left: 110px;
|
||||
mask-clip: view-box; /* should be the same as border-box */
|
||||
}
|
||||
|
||||
div.fill {
|
||||
left: 210px;
|
||||
mask-clip: fill-box; /* should be the same as content-box */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="outer mask stroke"></div>
|
||||
<div class="outer mask view"></div>
|
||||
<div class="outer mask fill"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS mask-clip reference</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<style type="text/css">
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg width="200" height="200" style="left: 10px;">
|
||||
<rect x="50" y="50" width="50" height="50" fill="blue"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 220px;">
|
||||
<rect x="50" y="50" width="50" height="50" fill="blue"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 10px; top: 220px;">
|
||||
<rect x="50" y="50" width="50" height="50" fill="green"/>
|
||||
<rect x="60" y="60" width="40" height="40" fill="blue"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 220px; top: 220px;">
|
||||
<rect x="50" y="50" width="50" height="50" fill="green"/>
|
||||
<rect x="60" y="60" width="40" height="40" fill="blue"/>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Masking: mask-clip: clip mask image</title>
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#the-mask-clip">
|
||||
<link rel="match" href="mask-clip-4-ref.html">
|
||||
<meta name="assert" content="content-box, padding-box, border-box, and
|
||||
magrin-box values of mask-clip should clip to the appropriate boxes.">
|
||||
<style type="text/css">
|
||||
svg {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
rect.mask {
|
||||
fill: blue;
|
||||
mask-origin: fill-box;
|
||||
mask-repeat: no-repeat;
|
||||
mask-image: url(support/50x50-opaque-blue.svg);
|
||||
}
|
||||
|
||||
rect.content {
|
||||
mask-clip: content-box; /* should be the same as fill-box */
|
||||
}
|
||||
|
||||
rect.padding {
|
||||
mask-clip: padding-box; /* should be the same as fill-box */
|
||||
}
|
||||
|
||||
rect.border {
|
||||
mask-clip: border-box; /* should be the same as stroke-box */
|
||||
}
|
||||
|
||||
rect.margin {
|
||||
mask-clip: margin-box; /* should be the same as stroke-box */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg width="200" height="200" style="left: 10px;">
|
||||
<rect class="content mask" x="50" y="50" width="150" height="150"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 220px;">
|
||||
<rect class="padding mask" x="50" y="50" width="150" height="150"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 10px; top: 220px;">
|
||||
<rect class="border mask" x="50" y="50" width="100" height="100" stroke="green" stroke-width="20"/>
|
||||
</svg>
|
||||
<svg width="200" height="200" style="left: 220px; top: 220px;">
|
||||
<rect class="margin mask" x="50" y="50" width="100" height="100" stroke="green" stroke-width="20"/>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user