Bug 1075457, part 1 - Implement rendering for |clip-path:polygon()|. r=mstange, r=jwatt

--HG--
extra : rebase_source : 17ddbe04589e146c5e64497527b5a74b54337b8b
This commit is contained in:
Dirk Schulze 2016-02-08 22:08:09 +00:00
parent c1e0702398
commit 7d71b51c43
31 changed files with 881 additions and 4 deletions

View File

@ -6617,6 +6617,14 @@ nsDisplaySVGEffects::PrintEffects(nsACString& aTo)
aTo += nsPrintfCString("clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
first = false;
}
const nsStyleSVGReset *style = mFrame->StyleSVGReset();
if (style->HasClipPath() && !clipPathFrame) {
if (!first) {
aTo += ", ";
}
aTo += "clip(basic-shape)";
first = false;
}
if (effectProperties.HasValidFilter()) {
if (!first) {
aTo += ", ";

View File

@ -0,0 +1,21 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path property and polygon function with absolute values</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-rectangle-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape
'polygon' for clipping. Test absolute value arguments. On pass you should
see a green square and no red.">
</head>
<body>
<p>The test passes if there is a green rectangle and no red.</p>
<div style="width: 150px; height: 100px; border: solid red 50px; background-color: green; clip-path: polygon(50px 50px, 200px 50px, 200px 150px, 50px 150px)"></div>
</body>
</html>

View File

@ -0,0 +1,24 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path property and polygon function with percentage values</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-rectangle-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape
'polygon' for clipping. Test percentage values for arguments. Percentage
values are relative to specified reference box. If no reference box was
specified, percentage values are relative to border-box. A number of
percentage values are specified as coordinates. On pass you should see a
green square and no red.">
</head>
<body>
<p>The test passes if there is a green rectangle and no red.</p>
<div style="width: 150px; height: 100px; border: solid red 50px; background-color: green; clip-path: polygon(20% 25%, 80% 25%, 80% 75%, 20% 75%)"></div>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path property and polygon function with absolute and percentage values</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-rectangle-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape
'polygon' for clipping. Test absolute and percentage value arguments. On
pass you should see a green square and no red.">
</head>
<body>
<p>The test passes if there is a green rectangle and no red.</p>
<div style="width: 150px; height: 100px; border: solid red 50px; background-color: green; position: absolute; clip-path: polygon(20% 50px, 200px 25%, 200px 150px, 20% 75%)"></div>
</body>
</html>

View File

@ -0,0 +1,25 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path property and polygon function with fill rule evenodd</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-rectangle-border-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape 'polygon' for clipping.
The point list for the polygon creates a 'whole' with the dimension of the background. With
the fill rule 'evenodd', this whole is clipped out. The clipping makes the green background
of the parent div box visible.
On pass you should see a green box with a blue border.">
</head>
<body>
<p>The test passes if there is a green rectangle with a blue border.</p>
<div style="background-color: green; width: 250px;">
<div style="width: 150px; height: 100px; border: solid blue 50px; background-color: red; clip-path: polygon(evenodd, 0 0, 250px 0, 250px 200px, 0 200px, 0 50px, 200px 50px, 200px 150px, 50px 150px, 50px 50px, 0 50px)"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path property and polygon function with fill rule nonzero</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-rectangle-border-ref.html">
<meta name="assert" content="The clip-path property takes the basic shape
'polygon' for clipping. The point list for the polygon creates a 'hole'
with the dimension of the background of the clipped element. With the fill
rule 'nonzero', this hole is clipped out. The clipping makes the green
background of the parent div box visible. On pass you should see a green
square with a blue border.">
</head>
<body>
<p>The test passes if there is a green rectangle with a blue border.</p>
<div style="background-color: green; width: 250px;">
<div style="width: 150px; height: 100px; border: solid blue 50px; background-color: red; clip-path: polygon(nonzero, 0 0, 250px 0, 250px 200px, 0 200px, 0 50px, 50px 50px, 50px 150px, 200px 150px, 200px 50px, 0 50px)"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with padding-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-square-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box 'padding-box' for the polygon() function by mixing percentage
and absolute values as coordinates. On sucess you should see a green square
and no red.">
</head>
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
}
</style>
<body>
<p>The test passes if there is a green square and no red.</p>
<div style="clip-path: polygon(0% 0%, 100% 0%, 100px 100%, 0 100px) padding-box"></div>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with border-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box 'border-box' for the polygon() function by mixing percentage
and absolute values as coordinates. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
border-left: lime solid 50px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(0% 25%, 50% 50px, 100px 75%, 0 150px) border-box"></div>
</body>
</html>

View File

@ -0,0 +1,35 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with margin-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-002-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box 'margin-box' for the polygon() function by mixing percentage
and absolute values as coordinates. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
</head>
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 25px;
border-left: lime solid 25px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(12.5% 25%, 37.5% 50px, 75px 50%, 25px 100px) margin-box"></div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with content-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-square-002-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box 'content-box' for the polygon() function by mixing percentage
and absolute values as coordinates. On sucess you should see a green square
and no red.">
</head>
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 25px;
}
</style>
<body>
<p>The test passes if there is a green square and no red.</p>
<div style="clip-path: polygon(0% 0px, 50px 0%, 100% 50px, 0px 100%) content-box"></div>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with fill-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box. 'fill-box' was specified but is not supported for HTML
elements. The used value should be 'border-box' for the polygon() function
instead. By mixing percentage and absolute values as coordinates we check
the correct used reference box. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
border-left: lime solid 50px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(0% 25%, 50% 50px, 100px 75%, 0 150px) fill-box"></div>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with stroke-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box. 'stroke-box' was specified but is not supported for HTML
elements. The used value should be 'border-box' for the polygon() function
instead. By mixing percentage and absolute values as coordinates we check
the correct used reference box. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
border-left: lime solid 50px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(0% 25%, 50% 50px, 100px 75%, 0 150px) stroke-box"></div>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with view-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box. 'view-box' was specified but is not supported for HTML
elements. The used value should be 'border-box' for the polygon() function
instead. By mixing percentage and absolute values as coordinates we check
the correct used reference box. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
border-left: lime solid 50px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(0% 25%, 50% 50px, 100px 75%, 0 150px) view-box"></div>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon different units</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-003-ref.html">
<meta name="assert" content="Test the support of different units for
polygon coordinates. The test passes if you see a multiple green and blue
stripe pairs. For each pair, the blue and green stripe must be of same
length.">
<style>
div {
width: 100%;
height: 20px;
background-color: green;
padding: 0;
margin: 0;
}
div:nth-child(odd) {
margin-bottom: 5px;
background-color: blue;
}
</style>
<body>
<p>The test passes if you see a multiple green and blue stripe pairs. For each pair, the blue and green stripe must be of same length.</p>
<div style="clip-path: polygon(0 0, 50% 0, 50% 20px, 0 20px)"></div>
<div style="width: 50%"></div>
<div style="clip-path: polygon(0 0, 20em 0, 20em 20px, 0 20px)"></div>
<div style="width: 20em"></div>
<!-- Activate when SVG2 is supported.
<div style="clip-path: polygon(0 0, 50vw 0, 50vw 20px, 0 20px)"></div>
<div style="width: 50vw"></div>
<div style="clip-path: polygon(0 0, 40vh 0, 40vh 20px, 0 20px)"></div>
<div style="width: 40vh"></div>
<div style="clip-path: polygon(0 0, calc(30% + 15px) 0, calc(30% + 15px) 20px, 0 20px)"></div>
<div style="width: calc(30% + 15px)"></div>-->
<div style="clip-path: polygon(0 0, 30ex 0, 30ex 20px, 0 20px)"></div>
<div style="width: 30ex"></div>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
</head>
<body>
<p>The test passes if there is a green rectangle with a blue border.</p>
<div style="width: 150px; height: 100px; border: solid blue 50px; background-color: green;"></div>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
</head>
<body>
<p>The test passes if there is a green rectangle and no red.</p>
<div style="margin-top: 50px; margin-left: 50px; position: absolute; width: 150px; height: 100px; background-color: green;"></div>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Reftest reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
</head>
<body>
<p>The test passes if there is a green square and no red.</p>
<div style="width: 100px; height: 100px; background-color: green; margin: 75px;"></div>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Reftest reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
</head>
<body>
<p>The test passes if there is a green square and no red.</p>
<div style="width: 50px; height: 50px; background-color: green; margin: 75px;"></div>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Test clip-path and polygon with border-box</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#clipping-paths">
<link rel="help" href="http://www.w3.org/TR/css-masking-1/#propdef-clip-path">
<link rel="match" href="clip-path-stripes-001-ref.html">
<meta name="assert" content="The clip-path property allows specifying
basic shapes and reference boxes. This test checks the usage of the correct
reference box 'border-box' for the polygon() function by mixing percentage
and absolute values as coordinates. On sucess you should see a green
vertical stripe next to a lime green vertical stripe. Both should be of equal
size.">
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 50px;
border-left: lime solid 50px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: url(#c1)"></div>
<svg>
<clipPath id="c1">
<rect x="0" y="50" width="100" height="100"/>
</clipPath>
</svg>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Reftest reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
</head>
<style>
div {
width: 50px;
height: 50px;
background-color: green;
padding: 25px;
margin: 25px;
border: red solid 25px;
border-left: lime solid 25px;
}
</style>
<body>
<p>The test passes if you see a green vertical stripe next to a lime green vertical stripe, both stripes should be of equal size and there should be no red.</p>
<div style="clip-path: polygon(12.5% 25%, 37.5% 50px, 75px 50%, 25px 100px) margin-box"></div>
<svg>
<clipPath id="c1">
<rect x="0" y="50" width="50" height="50"/>
</clipPath>
</svg>
</body>
</html>

View File

@ -0,0 +1,63 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>CSS Masking: Reftest reference</title>
<link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com">
<style>
div {
height: 20px;
width: 100%;
background-color: green;
padding: 0;
margin: 0;
}
div:nth-child(odd) {
margin-bottom: 5px;
background-color: blue;
}
</style>
<body>
<p>The test passes if you see a multiple green and blue stripe pairs. For each pair, the blue and green stripe must be of same length.</p>
<div style="clip-path: url(#c1)"></div>
<div style="width: 50%"></div>
<div style="clip-path: url(#c2)"></div>
<div style="width: 20em"></div>
<!--<div style="clip-path: url(#c3)"></div>
<div style="width: 50vw"></div>
<div style="clip-path: url(#c4)"></div>
<div style="width: 40vh"></div>
<div style="clip-path: url(#c5)"></div>
<div style="width: calc(30% + 15px)"></div>-->
<div style="clip-path: url(#c6)"></div>
<div style="width: 30ex"></div>
<svg>
<clipPath id="c1" clipPathUnits="objectBoundingBox">
<rect width="0.5" height="1"/>
</clipPath>
<clipPath id="c2">
<rect width="20em" height="20"/>
</clipPath>
<!--<clipPath id="c3">
<rect width="50vw" height="20"/>
</clipPath>
<clipPath id="c4">
<rect width="40vh" height="20"/>
</clipPath>
<clipPath id="c5">
<rect width="calc(30% + 15px)" height="20"/>
</clipPath>-->
<clipPath id="c6">
<rect width="30ex" height="20"/>
</clipPath>
</svg>
</body>
</html>

View File

@ -0,0 +1,19 @@
# These tests verify that CSS clip-path behaves properly.
# e.g. clip-path: polygon(nonzero, 3px 3px, 20% 20%)
default-preferences pref(layout.css.clip-path-shapes.enabled,true)
# Following tests adapted from W3C csswg-test repo
== clip-path-polygon-001.html clip-path-rectangle-ref.html
== clip-path-polygon-002.html clip-path-rectangle-ref.html
== clip-path-polygon-003.html clip-path-rectangle-ref.html
== clip-path-polygon-004.html clip-path-rectangle-border-ref.html
== clip-path-polygon-005.html clip-path-rectangle-border-ref.html
== clip-path-polygon-006.html clip-path-square-001-ref.html
== clip-path-polygon-007.html clip-path-stripes-001-ref.html
== clip-path-polygon-008.html clip-path-stripes-002-ref.html
== clip-path-polygon-009.html clip-path-square-002-ref.html
== clip-path-polygon-010.html clip-path-stripes-001-ref.html
== clip-path-polygon-011.html clip-path-stripes-001-ref.html
== clip-path-polygon-012.html clip-path-stripes-001-ref.html
== clip-path-polygon-013.html clip-path-stripes-003-ref.html

View File

@ -1,3 +1,6 @@
# clip-path tests
include clip-path/reftest.list
== clipPath-html-01.xhtml clipPath-html-01-ref.svg
== clipPath-html-01-extref.xhtml clipPath-html-01-ref.svg
== clipPath-html-02.xhtml clipPath-html-02-ref.svg

View File

@ -3480,6 +3480,10 @@ struct nsStyleSVGReset
return !mFilters.IsEmpty();
}
bool HasClipPath() const {
return mClipPath.GetType() != NS_STYLE_CLIP_PATH_NONE;
}
bool HasNonScalingStroke() const {
return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
}

View File

@ -134,6 +134,7 @@ support-files = file_bug1089417_iframe.html
[test_bug1232829.html]
[test_cascade.html]
[test_ch_ex_no_infloops.html]
[test_clip-path_polygon.html]
[test_compute_data_with_start_struct.html]
skip-if = toolkit == 'android'
[test_computed_style.html]

View File

@ -0,0 +1,41 @@
<html>
<head>
<style>
body {padding: 0;margin:0;}
div {
width: 200px;
height: 200px;
position: fixed;
top: 50px;
left: 50px;
margin: 50;
padding: 50;
border: 50px solid red;
transform-origin: 0 0;
transform: translate(50px, 50px) scale(0.5);
background-color: green;
clip-path: polygon(0 0, 200px 0, 0 200px) content-box;*/
}
</style>
<title>clip-path with polygon() hit test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<div id="a"></div>
<p style="margin-top: 110px">
<script>
var a = document.getElementById("a");
if (SpecialPowers.getBoolPref("layout.css.clip-path-shapes.enabled")) {
isnot(a, document.elementFromPoint(199, 199), "a shouldn't be found");
isnot(a, document.elementFromPoint(199, 250), "a shouldn't be found");
isnot(a, document.elementFromPoint(250, 199), "a shouldn't be found");
isnot(a, document.elementFromPoint(255, 255), "a shouldn't be found");
isnot(a, document.elementFromPoint(301, 200), "a shouldn't be found");
isnot(a, document.elementFromPoint(200, 301), "a shouldn't be found");
}
is(a, document.elementFromPoint(200, 200), "a should be found");
is(a, document.elementFromPoint(299, 200), "a should be found");
is(a, document.elementFromPoint(200, 299), "a should be found");
is(a, document.elementFromPoint(250, 250), "a should be found");
</script>
</html>

View File

@ -18,6 +18,7 @@ EXPORTS += [
]
UNIFIED_SOURCES += [
'nsCSSClipPathInstance.cpp',
'nsCSSFilterInstance.cpp',
'nsFilterInstance.cpp',
'nsSVGAFrame.cpp',

View File

@ -0,0 +1,135 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Main header first:
#include "nsCSSClipPathInstance.h"
#include "gfx2DGlue.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/2D.h"
#include "nsIFrame.h"
#include "nsRenderingContext.h"
#include "nsRuleNode.h"
using namespace mozilla;
using namespace mozilla::gfx;
/* static*/ void
nsCSSClipPathInstance::ApplyBasicShapeClip(gfxContext& aContext,
nsIFrame* aFrame)
{
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
int32_t type = clipPathStyle.GetType();
MOZ_ASSERT(type != NS_STYLE_CLIP_PATH_NONE, "unexpected none value");
// In the future nsCSSClipPathInstance may handle <clipPath> references as
// well. For the time being return early.
if (type == NS_STYLE_CLIP_PATH_URL) {
return;
}
nsCSSClipPathInstance instance(aFrame, clipPathStyle);
aContext.NewPath();
RefPtr<Path> path = instance.CreateClipPath(aContext.GetDrawTarget());
aContext.SetPath(path);
aContext.Clip();
}
/* static*/ bool
nsCSSClipPathInstance::HitTestBasicShapeClip(nsIFrame* aFrame,
const gfxPoint& aPoint)
{
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
int32_t type = clipPathStyle.GetType();
MOZ_ASSERT(type != NS_STYLE_CLIP_PATH_NONE, "unexpected none value");
// In the future nsCSSClipPathInstance may handle <clipPath> references as
// well. For the time being return early.
if (type == NS_STYLE_CLIP_PATH_URL) {
return false;
}
nsCSSClipPathInstance instance(aFrame, clipPathStyle);
RefPtr<DrawTarget> drawTarget =
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
RefPtr<Path> path = instance.CreateClipPath(drawTarget);
float pixelRatio = float(nsPresContext::AppUnitsPerCSSPixel()) /
aFrame->PresContext()->AppUnitsPerDevPixel();
return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
}
already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
{
nsRect r;
// XXXkrit SVG needs to use different boxes.
switch (mClipPathStyle.GetSizingBox()) {
case NS_STYLE_CLIP_SHAPE_SIZING_CONTENT:
r = mTargetFrame->GetContentRectRelativeToSelf();
break;
case NS_STYLE_CLIP_SHAPE_SIZING_PADDING:
r = mTargetFrame->GetPaddingRectRelativeToSelf();
break;
case NS_STYLE_CLIP_SHAPE_SIZING_MARGIN:
r = mTargetFrame->GetMarginRectRelativeToSelf();
break;
default: // Use the border box
r = mTargetFrame->GetRectRelativeToSelf();
}
if (mClipPathStyle.GetType() != NS_STYLE_CLIP_PATH_SHAPE) {
// TODO Clip to border-radius/reference box if no shape
// was specified.
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
return builder->Finish();
}
nscoord appUnitsPerDevPixel =
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
r = ToAppUnits(r.ToNearestPixels(appUnitsPerDevPixel), appUnitsPerDevPixel);
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
switch (basicShape->GetShapeType()) {
case nsStyleBasicShape::Type::ePolygon:
return CreateClipPathPolygon(aDrawTarget, r);
case nsStyleBasicShape::Type::eCircle:
case nsStyleBasicShape::Type::eEllipse:
case nsStyleBasicShape::Type::eInset:
// XXXkrit support all basic shapes
break;
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type");
}
// Return an empty Path:
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
return builder->Finish();
}
already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox)
{
nsStyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
const nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
MOZ_ASSERT(coords.Length() % 2 == 0 &&
coords.Length() >= 2, "wrong number of arguments");
FillRule fillRule = basicShape->GetFillRule() == NS_STYLE_FILL_RULE_NONZERO ?
FillRule::FILL_WINDING : FillRule::FILL_EVEN_ODD;
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(fillRule);
nscoord x = nsRuleNode::ComputeCoordPercentCalc(coords[0], aRefBox.width);
nscoord y = nsRuleNode::ComputeCoordPercentCalc(coords[1], aRefBox.height);
nscoord appUnitsPerDevPixel =
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
builder->MoveTo(Point(aRefBox.x + x, aRefBox.y + y) / appUnitsPerDevPixel);
for (size_t i = 2; i < coords.Length(); i += 2) {
x = nsRuleNode::ComputeCoordPercentCalc(coords[i], aRefBox.width);
y = nsRuleNode::ComputeCoordPercentCalc(coords[i + 1], aRefBox.height);
builder->LineTo(Point(aRefBox.x + x, aRefBox.y + y) / appUnitsPerDevPixel);
}
builder->Close();
return builder->Finish();
}

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __NS_CSSCLIPPATHINSTANCE_H__
#define __NS_CSSCLIPPATHINSTANCE_H__
#include "nsStyleStruct.h"
#include "nsRect.h"
#include "mozilla/gfx/2D.h"
class nsIFrame;
class nsRenderingContext;
namespace mozilla {
class nsCSSClipPathInstance
{
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Path Path;
public:
static void ApplyBasicShapeClip(gfxContext& aContext,
nsIFrame* aFrame);
// aPoint is in CSS pixels.
static bool HitTestBasicShapeClip(nsIFrame* aFrame,
const gfxPoint& aPoint);
private:
explicit nsCSSClipPathInstance(nsIFrame* aFrame,
const nsStyleClipPath aClipPathStyle)
: mTargetFrame(aFrame)
, mClipPathStyle(aClipPathStyle)
{
}
already_AddRefed<Path> CreateClipPath(DrawTarget* aDrawTarget);
already_AddRefed<Path> CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
/**
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
nsStyleClipPath mClipPathStyle;
};
} // namespace mozilla
#endif

View File

@ -9,6 +9,7 @@
// Keep others in (case-insensitive) order:
#include "gfxDrawable.h"
#include "nsCSSAnonBoxes.h"
#include "nsCSSClipPathInstance.h"
#include "nsDisplayList.h"
#include "nsFilterInstance.h"
#include "nsLayoutUtils.h"
@ -155,8 +156,7 @@ nsSVGIntegrationUtils::UsingEffectsForFrame(const nsIFrame* aFrame)
const nsStyleSVGReset *style = aFrame->StyleSVGReset();
bool hasValidLayers = style->mMask.HasLayerWithImage();
return (style->HasFilters() || hasValidLayers ||
(style->mClipPath.GetType() != NS_STYLE_CLIP_PATH_NONE));
return (style->HasFilters() || style->HasClipPath() || hasValidLayers);
}
// For non-SVG frames, this gives the offset to the frame's "user space".
@ -636,6 +636,9 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext,
if (clipPathFrame && isTrivialClip) {
aContext.Save();
clipPathFrame->ApplyClipPath(aContext, aFrame, cssPxToDevPxMatrix);
} else if (!clipPathFrame && svgReset->HasClipPath()) {
aContext.Save();
nsCSSClipPathInstance::ApplyBasicShapeClip(aContext, aFrame);
}
/* Paint the child */
@ -656,7 +659,8 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(gfxContext& aContext,
basic->SetTarget(oldCtx);
}
if (clipPathFrame && isTrivialClip) {
if ((clipPathFrame && isTrivialClip) ||
(!clipPathFrame && svgReset->HasClipPath())) {
aContext.Restore();
}

View File

@ -18,6 +18,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PatternHelpers.h"
#include "mozilla/Preferences.h"
#include "nsCSSClipPathInstance.h"
#include "nsCSSFrameConstructor.h"
#include "nsDisplayList.h"
#include "nsFilterInstance.h"
@ -725,8 +726,13 @@ nsSVGUtils::HitTestClip(nsIFrame *aFrame, const gfxPoint &aPoint)
{
nsSVGEffects::EffectProperties props =
nsSVGEffects::GetEffectProperties(aFrame);
if (!props.mClipPath)
if (!props.mClipPath) {
const nsStyleSVGReset *style = aFrame->StyleSVGReset();
if (style->HasClipPath()) {
return nsCSSClipPathInstance::HitTestBasicShapeClip(aFrame, aPoint);
}
return true;
}
bool isOK = true;
nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame(&isOK);