зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1823463 - Render clip-path:shape(). r=emilio
Update clip-path-shape-003.html and clip-path-shape-004.html because 1. Per SVG2 spec, we don't accept comma among commands, so I remove them. 2. Basically, these two tests want to test the result of `shape()` should be identical to the result of `path()`. However, I noticed the original tests which put a `clip-path:path()` with `position:absolutely` may have a fuzzy result if the path has some curves there. This may be caused by anti-alias together with absoultely positioned element (note: perhaps there are some floating point calculation in layout for this, so the final rendering coordinates may have some fractions). Therefore, I drop the absolutely positioned element, and just test that if the result of `shape()` is identical to the result of `path()`. Also, add two more tests for different reference-boxes together with the usage of `shape()` (to make sure we resolve percentage values properly). Differential Revision: https://phabricator.services.mozilla.com/D202884
This commit is contained in:
Родитель
6605350dc6
Коммит
86adb0bd63
|
@ -556,11 +556,30 @@ already_AddRefed<Path> SVGPathData::BuildPathForMeasuring(
|
||||||
return BuildPath(aPath, builder, StyleStrokeLinecap::Butt, 0);
|
return BuildPath(aPath, builder, StyleStrokeLinecap::Butt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline StyleCSSFloat GetRotate(const StyleCSSFloat& aAngle) {
|
||||||
|
return aAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline StyleCSSFloat GetRotate(const StyleAngle& aAngle) {
|
||||||
|
return aAngle.ToDegrees();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline StyleCSSFloat Resolve(const StyleCSSFloat& aValue,
|
||||||
|
CSSCoord aBasis) {
|
||||||
|
return aValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline StyleCSSFloat Resolve(const LengthPercentage& aValue,
|
||||||
|
CSSCoord aBasis) {
|
||||||
|
return aValue.ResolveToCSSPixels(aBasis);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Angle, typename LP>
|
template <typename Angle, typename LP>
|
||||||
static already_AddRefed<Path> BuildPathInternal(
|
static already_AddRefed<Path> BuildPathInternal(
|
||||||
Span<const StyleGenericShapeCommand<Angle, LP>> aPath,
|
Span<const StyleGenericShapeCommand<Angle, LP>> aPath,
|
||||||
PathBuilder* aBuilder, StyleStrokeLinecap aStrokeLineCap,
|
PathBuilder* aBuilder, StyleStrokeLinecap aStrokeLineCap,
|
||||||
Float aStrokeWidth, const Point& aOffset, float aZoomFactor) {
|
Float aStrokeWidth, const CSSSize& aPercentageBasis, const Point& aOffset,
|
||||||
|
float aZoomFactor) {
|
||||||
using Command = StyleGenericShapeCommand<Angle, LP>;
|
using Command = StyleGenericShapeCommand<Angle, LP>;
|
||||||
|
|
||||||
if (aPath.IsEmpty() || !aPath[0].IsMove()) {
|
if (aPath.IsEmpty() || !aPath[0].IsMove()) {
|
||||||
|
@ -609,14 +628,14 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
break;
|
break;
|
||||||
case Command::Tag::Move: {
|
case Command::Tag::Move: {
|
||||||
maybeApproximateZeroLengthSubpathSquareCaps(prevSeg, seg);
|
maybeApproximateZeroLengthSubpathSquareCaps(prevSeg, seg);
|
||||||
const Point& p = cmd.move.point.ToGfxPoint();
|
const Point& p = cmd.move.point.ToGfxPoint(aPercentageBasis);
|
||||||
pathStart = segEnd = cmd.move.by_to == StyleByTo::To ? p : segStart + p;
|
pathStart = segEnd = cmd.move.by_to == StyleByTo::To ? p : segStart + p;
|
||||||
aBuilder->MoveTo(scale(segEnd));
|
aBuilder->MoveTo(scale(segEnd));
|
||||||
subpathHasLength = false;
|
subpathHasLength = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Command::Tag::Line: {
|
case Command::Tag::Line: {
|
||||||
const Point& p = cmd.line.point.ToGfxPoint();
|
const Point& p = cmd.line.point.ToGfxPoint(aPercentageBasis);
|
||||||
segEnd = cmd.line.by_to == StyleByTo::To ? p : segStart + p;
|
segEnd = cmd.line.by_to == StyleByTo::To ? p : segStart + p;
|
||||||
if (segEnd != segStart) {
|
if (segEnd != segStart) {
|
||||||
subpathHasLength = true;
|
subpathHasLength = true;
|
||||||
|
@ -625,9 +644,9 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Command::Tag::CubicCurve:
|
case Command::Tag::CubicCurve:
|
||||||
cp1 = cmd.cubic_curve.control1.ToGfxPoint();
|
cp1 = cmd.cubic_curve.control1.ToGfxPoint(aPercentageBasis);
|
||||||
cp2 = cmd.cubic_curve.control2.ToGfxPoint();
|
cp2 = cmd.cubic_curve.control2.ToGfxPoint(aPercentageBasis);
|
||||||
segEnd = cmd.cubic_curve.point.ToGfxPoint();
|
segEnd = cmd.cubic_curve.point.ToGfxPoint(aPercentageBasis);
|
||||||
|
|
||||||
if (cmd.cubic_curve.by_to == StyleByTo::By) {
|
if (cmd.cubic_curve.by_to == StyleByTo::By) {
|
||||||
cp1 += segStart;
|
cp1 += segStart;
|
||||||
|
@ -642,8 +661,8 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::Tag::QuadCurve:
|
case Command::Tag::QuadCurve:
|
||||||
cp1 = cmd.quad_curve.control1.ToGfxPoint();
|
cp1 = cmd.quad_curve.control1.ToGfxPoint(aPercentageBasis);
|
||||||
segEnd = cmd.quad_curve.point.ToGfxPoint();
|
segEnd = cmd.quad_curve.point.ToGfxPoint(aPercentageBasis);
|
||||||
|
|
||||||
if (cmd.quad_curve.by_to == StyleByTo::By) {
|
if (cmd.quad_curve.by_to == StyleByTo::By) {
|
||||||
cp1 += segStart;
|
cp1 += segStart;
|
||||||
|
@ -662,8 +681,8 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
|
|
||||||
case Command::Tag::Arc: {
|
case Command::Tag::Arc: {
|
||||||
const auto& arc = cmd.arc;
|
const auto& arc = cmd.arc;
|
||||||
const Point& radii = arc.radii.ToGfxPoint();
|
const Point& radii = arc.radii.ToGfxPoint(aPercentageBasis);
|
||||||
segEnd = arc.point.ToGfxPoint();
|
segEnd = arc.point.ToGfxPoint(aPercentageBasis);
|
||||||
if (arc.by_to == StyleByTo::By) {
|
if (arc.by_to == StyleByTo::By) {
|
||||||
segEnd += segStart;
|
segEnd += segStart;
|
||||||
}
|
}
|
||||||
|
@ -674,8 +693,9 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
} else {
|
} else {
|
||||||
const bool arc_is_large = arc.arc_size == StyleArcSize::Large;
|
const bool arc_is_large = arc.arc_size == StyleArcSize::Large;
|
||||||
const bool arc_is_cw = arc.arc_sweep == StyleArcSweep::Cw;
|
const bool arc_is_cw = arc.arc_sweep == StyleArcSweep::Cw;
|
||||||
SVGArcConverter converter(segStart, segEnd, radii, arc.rotate,
|
SVGArcConverter converter(segStart, segEnd, radii,
|
||||||
arc_is_large, arc_is_cw);
|
GetRotate(arc.rotate), arc_is_large,
|
||||||
|
arc_is_cw);
|
||||||
while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
|
while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
|
||||||
aBuilder->BezierTo(scale(cp1), scale(cp2), scale(segEnd));
|
aBuilder->BezierTo(scale(cp1), scale(cp2), scale(segEnd));
|
||||||
}
|
}
|
||||||
|
@ -683,11 +703,12 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Command::Tag::HLine:
|
case Command::Tag::HLine: {
|
||||||
|
const float x = Resolve(cmd.h_line.x, aPercentageBasis.width);
|
||||||
if (cmd.h_line.by_to == StyleByTo::To) {
|
if (cmd.h_line.by_to == StyleByTo::To) {
|
||||||
segEnd = Point(cmd.h_line.x, segStart.y);
|
segEnd = Point(x, segStart.y);
|
||||||
} else {
|
} else {
|
||||||
segEnd = segStart + Point(cmd.h_line.x, 0.0f);
|
segEnd = segStart + Point(x, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segEnd != segStart) {
|
if (segEnd != segStart) {
|
||||||
|
@ -695,12 +716,13 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
aBuilder->LineTo(scale(segEnd));
|
aBuilder->LineTo(scale(segEnd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Command::Tag::VLine:
|
case Command::Tag::VLine: {
|
||||||
|
const float y = Resolve(cmd.v_line.y, aPercentageBasis.height);
|
||||||
if (cmd.v_line.by_to == StyleByTo::To) {
|
if (cmd.v_line.by_to == StyleByTo::To) {
|
||||||
segEnd = Point(segStart.x, cmd.v_line.y);
|
segEnd = Point(segStart.x, y);
|
||||||
} else {
|
} else {
|
||||||
segEnd = segStart + Point(0.0f, cmd.v_line.y);
|
segEnd = segStart + Point(0.0f, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segEnd != segStart) {
|
if (segEnd != segStart) {
|
||||||
|
@ -708,11 +730,11 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
aBuilder->LineTo(scale(segEnd));
|
aBuilder->LineTo(scale(segEnd));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Command::Tag::SmoothCubic:
|
case Command::Tag::SmoothCubic:
|
||||||
cp1 = prevSeg && prevSeg->IsCubicType() ? segStart * 2 - cp2 : segStart;
|
cp1 = prevSeg && prevSeg->IsCubicType() ? segStart * 2 - cp2 : segStart;
|
||||||
cp2 = cmd.smooth_cubic.control2.ToGfxPoint();
|
cp2 = cmd.smooth_cubic.control2.ToGfxPoint(aPercentageBasis);
|
||||||
segEnd = cmd.smooth_cubic.point.ToGfxPoint();
|
segEnd = cmd.smooth_cubic.point.ToGfxPoint(aPercentageBasis);
|
||||||
|
|
||||||
if (cmd.smooth_cubic.by_to == StyleByTo::By) {
|
if (cmd.smooth_cubic.by_to == StyleByTo::By) {
|
||||||
cp2 += segStart;
|
cp2 += segStart;
|
||||||
|
@ -731,7 +753,7 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
// Convert quadratic curve to cubic curve:
|
// Convert quadratic curve to cubic curve:
|
||||||
tcp1 = segStart + (cp1 - segStart) * 2 / 3;
|
tcp1 = segStart + (cp1 - segStart) * 2 / 3;
|
||||||
|
|
||||||
const Point& p = cmd.smooth_quad.point.ToGfxPoint();
|
const Point& p = cmd.smooth_quad.point.ToGfxPoint(aPercentageBasis);
|
||||||
// set before setting tcp2!
|
// set before setting tcp2!
|
||||||
segEnd = cmd.smooth_quad.by_to == StyleByTo::To ? p : segStart + p;
|
segEnd = cmd.smooth_quad.by_to == StyleByTo::To ? p : segStart + p;
|
||||||
tcp2 = cp1 + (segEnd - cp1) / 3;
|
tcp2 = cp1 + (segEnd - cp1) / 3;
|
||||||
|
@ -756,16 +778,22 @@ static already_AddRefed<Path> BuildPathInternal(
|
||||||
return aBuilder->Finish();
|
return aBuilder->Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could simplify this function because this is only used by CSS motion path
|
|
||||||
// and clip-path, which don't render the SVG Path. i.e. The returned path is
|
|
||||||
// used as a reference.
|
|
||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<Path> SVGPathData::BuildPath(
|
already_AddRefed<Path> SVGPathData::BuildPath(
|
||||||
Span<const StylePathCommand> aPath, PathBuilder* aBuilder,
|
Span<const StylePathCommand> aPath, PathBuilder* aBuilder,
|
||||||
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
||||||
const gfx::Point& aOffset, float aZoomFactor) {
|
const CSSSize& aBasis, const gfx::Point& aOffset, float aZoomFactor) {
|
||||||
return BuildPathInternal(aPath, aBuilder, aStrokeLineCap, aStrokeWidth,
|
return BuildPathInternal(aPath, aBuilder, aStrokeLineCap, aStrokeWidth,
|
||||||
aOffset, aZoomFactor);
|
aBasis, aOffset, aZoomFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<Path> SVGPathData::BuildPath(
|
||||||
|
Span<const StyleShapeCommand> aShape, PathBuilder* aBuilder,
|
||||||
|
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
||||||
|
const CSSSize& aBasis, const gfx::Point& aOffset, float aZoomFactor) {
|
||||||
|
return BuildPathInternal(aShape, aBuilder, aStrokeLineCap, aStrokeWidth,
|
||||||
|
aBasis, aOffset, aZoomFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double AngleOfVector(const Point& aVector) {
|
static double AngleOfVector(const Point& aVector) {
|
||||||
|
|
|
@ -190,14 +190,22 @@ class SVGPathData {
|
||||||
Span<const StylePathCommand> aPath);
|
Span<const StylePathCommand> aPath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function tries to build the path from an array of StylePathCommand,
|
* This function tries to build the path from an array of GenericShapeCommand,
|
||||||
* which is generated by cbindgen from Rust (see ServoStyleConsts.h).
|
* which is generated by cbindgen from Rust (see ServoStyleConsts.h).
|
||||||
* Basically, this is a variant of the above BuildPath() functions.
|
* Basically, this is a variant of the above BuildPath() functions.
|
||||||
|
* Note: |StylePathCommand| doesn't accept percentage values, so its |aBasis|
|
||||||
|
* is empty by default.
|
||||||
*/
|
*/
|
||||||
static already_AddRefed<Path> BuildPath(
|
static already_AddRefed<Path> BuildPath(
|
||||||
Span<const StylePathCommand> aPath, PathBuilder* aBuilder,
|
Span<const StylePathCommand> aPath, PathBuilder* aBuilder,
|
||||||
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
||||||
const gfx::Point& aOffset = gfx::Point(), float aZoomFactor = 1.0);
|
const CSSSize& aBasis = {}, const gfx::Point& aOffset = gfx::Point(),
|
||||||
|
float aZoomFactor = 1.0);
|
||||||
|
static already_AddRefed<Path> BuildPath(
|
||||||
|
Span<const StyleShapeCommand> aShape, PathBuilder* aBuilder,
|
||||||
|
StyleStrokeLinecap aStrokeLineCap, Float aStrokeWidth,
|
||||||
|
const CSSSize& aBasis, const gfx::Point& aOffset = gfx::Point(),
|
||||||
|
float aZoomFactor = 1.0);
|
||||||
|
|
||||||
const_iterator begin() const { return mData.Elements(); }
|
const_iterator begin() const { return mData.Elements(); }
|
||||||
const_iterator end() const { return mData.Elements() + mData.Length(); }
|
const_iterator end() const { return mData.Elements() + mData.Length(); }
|
||||||
|
|
|
@ -1202,10 +1202,19 @@ inline nsRect StyleZoom::Unzoom(const nsRect& aValue) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline gfx::Point StyleCoordinatePair<StyleCSSFloat>::ToGfxPoint() const {
|
inline gfx::Point StyleCoordinatePair<StyleCSSFloat>::ToGfxPoint(
|
||||||
|
const CSSSize* aBasis) const {
|
||||||
return gfx::Point(x, y);
|
return gfx::Point(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline gfx::Point StyleCoordinatePair<LengthPercentage>::ToGfxPoint(
|
||||||
|
const CSSSize* aBasis) const {
|
||||||
|
MOZ_ASSERT(aBasis);
|
||||||
|
return gfx::Point(x.ResolveToCSSPixels(aBasis->Width()),
|
||||||
|
y.ResolveToCSSPixels(aBasis->Height()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -66,7 +66,7 @@ bool CSSClipPathInstance::HitTestBasicShapeOrPathClip(nsIFrame* aFrame,
|
||||||
RefPtr<Path> path = instance.CreateClipPath(
|
RefPtr<Path> path = instance.CreateClipPath(
|
||||||
drawTarget, SVGUtils::GetCSSPxToDevPxMatrix(aFrame));
|
drawTarget, SVGUtils::GetCSSPxToDevPxMatrix(aFrame));
|
||||||
float pixelRatio = float(AppUnitsPerCSSPixel()) /
|
float pixelRatio = float(AppUnitsPerCSSPixel()) /
|
||||||
aFrame->PresContext()->AppUnitsPerDevPixel();
|
float(aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
return path && path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
|
return path && path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +124,7 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPath(
|
||||||
case StyleBasicShape::Tag::Path:
|
case StyleBasicShape::Tag::Path:
|
||||||
return CreateClipPathPath(aDrawTarget, r);
|
return CreateClipPathPath(aDrawTarget, r);
|
||||||
case StyleBasicShape::Tag::Shape:
|
case StyleBasicShape::Tag::Shape:
|
||||||
// TODO: Support shape() in this patch series.
|
return CreateClipPathShape(aDrawTarget, r);
|
||||||
return nullptr;
|
|
||||||
default:
|
default:
|
||||||
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type");
|
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type");
|
||||||
}
|
}
|
||||||
|
@ -183,13 +182,36 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPathPath(
|
||||||
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
|
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
|
||||||
path.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
|
path.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
|
||||||
: FillRule::FILL_EVEN_ODD);
|
: FillRule::FILL_EVEN_ODD);
|
||||||
nscoord appUnitsPerDevPixel =
|
const nscoord appUnitsPerDevPixel =
|
||||||
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
|
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
float scale = float(AppUnitsPerCSSPixel()) / appUnitsPerDevPixel;
|
const Point offset =
|
||||||
Point offset = Point(aRefBox.x, aRefBox.y) / appUnitsPerDevPixel;
|
LayoutDevicePoint::FromAppUnits(aRefBox.TopLeft(), appUnitsPerDevPixel)
|
||||||
|
.ToUnknownPoint();
|
||||||
|
const float scale = float(AppUnitsPerCSSPixel()) / float(appUnitsPerDevPixel);
|
||||||
|
|
||||||
return SVGPathData::BuildPath(path.path._0.AsSpan(), builder,
|
return SVGPathData::BuildPath(path.path._0.AsSpan(), builder,
|
||||||
StyleStrokeLinecap::Butt, 0.0, offset, scale);
|
StyleStrokeLinecap::Butt, 0.0, {}, offset,
|
||||||
|
scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Path> CSSClipPathInstance::CreateClipPathShape(
|
||||||
|
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
|
||||||
|
const auto& shape = mClipPathStyle.AsShape()._0->AsShape();
|
||||||
|
|
||||||
|
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
|
||||||
|
shape.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
|
||||||
|
: FillRule::FILL_EVEN_ODD);
|
||||||
|
const nscoord appUnitsPerDevPixel =
|
||||||
|
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
const CSSSize basis = CSSSize::FromAppUnits(aRefBox.Size());
|
||||||
|
const Point offset =
|
||||||
|
LayoutDevicePoint::FromAppUnits(aRefBox.TopLeft(), appUnitsPerDevPixel)
|
||||||
|
.ToUnknownPoint();
|
||||||
|
const float scale = float(AppUnitsPerCSSPixel()) / float(appUnitsPerDevPixel);
|
||||||
|
|
||||||
|
return SVGPathData::BuildPath(shape.commands.AsSpan(), builder,
|
||||||
|
StyleStrokeLinecap::Butt, 0.0, basis, offset,
|
||||||
|
scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -58,6 +58,9 @@ class MOZ_STACK_CLASS CSSClipPathInstance {
|
||||||
already_AddRefed<Path> CreateClipPathPath(DrawTarget* aDrawTarget,
|
already_AddRefed<Path> CreateClipPathPath(DrawTarget* aDrawTarget,
|
||||||
const nsRect& aRefBox);
|
const nsRect& aRefBox);
|
||||||
|
|
||||||
|
already_AddRefed<Path> CreateClipPathShape(DrawTarget* aDrawTarget,
|
||||||
|
const nsRect& aRefBox);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The frame for the element that is currently being clipped.
|
* The frame for the element that is currently being clipped.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -214,6 +214,7 @@ include = [
|
||||||
"BasicShape",
|
"BasicShape",
|
||||||
"InsetRect",
|
"InsetRect",
|
||||||
"ShapeRadius",
|
"ShapeRadius",
|
||||||
|
"ShapeCommand",
|
||||||
"ArcSlice",
|
"ArcSlice",
|
||||||
"ForgottenArcSlicePtr",
|
"ForgottenArcSlicePtr",
|
||||||
"HeaderWithLength",
|
"HeaderWithLength",
|
||||||
|
@ -758,7 +759,10 @@ renaming_overrides_prefixing = true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"CoordinatePair" = """
|
"CoordinatePair" = """
|
||||||
inline gfx::Point ToGfxPoint() const;
|
inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
|
||||||
|
gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
|
||||||
|
return ToGfxPoint(&aBasis);
|
||||||
|
};
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"TextOverflow" = """
|
"TextOverflow" = """
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-interpolation-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-interpolation-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-002-units.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[clip-path-shape-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -8,15 +8,6 @@
|
||||||
'shape()' for clipping. Test curves.">
|
'shape()' for clipping. Test curves.">
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
div {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
#ref {
|
|
||||||
clip-path: path(nonzero, "M 10 10, Q 40 0 60 20, T 90 0, c 10 40 20 20 -20 60, s -10 70 -40 -10");
|
|
||||||
background-color: red;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
#rect {
|
#rect {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
@ -29,8 +20,6 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<p>You should see no red.</p>
|
|
||||||
<div id="ref"></div>
|
|
||||||
<div id="rect"></div>
|
<div id="rect"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,15 +8,6 @@
|
||||||
'shape()' for clipping. Test arcs.">
|
'shape()' for clipping. Test arcs.">
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
div {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
#ref {
|
|
||||||
clip-path: path(nonzero, "M 20 20 A 25 12 0 0 1 80 20, a 33 33 120 1 1 -40 50, A 20 25 0 0 0 20 20");
|
|
||||||
background-color: red;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
#rect {
|
#rect {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
@ -28,8 +19,6 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<p>You should see no red.</p>
|
|
||||||
<div id="ref"></div>
|
|
||||||
<div id="rect"></div>
|
<div id="rect"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CSS Masking: Test clip-path property and shape function with padding-box</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
||||||
|
<link rel="match" href="reference/clip-path-path-001-ref.html">
|
||||||
|
<meta name="assert" content="The clip-path property takes the basic shape
|
||||||
|
'shape()' for clipping. Test the usage of the reference box. On pass you
|
||||||
|
should see a green square.">
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
#rect {
|
||||||
|
/* The size of the padding-box is 100x100. */
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 10px solid red;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: green;
|
||||||
|
clip-path: shape(from 0px 0px,
|
||||||
|
hline by 80px, vline by 80%, hline by -80%, close)
|
||||||
|
padding-box;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<p>The test passes if there are a green filled rect.</p>
|
||||||
|
<div id="rect"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CSS Masking: Test clip-path property and shape function with content-box</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
||||||
|
<link rel="match" href="reference/clip-path-path-001-ref.html">
|
||||||
|
<meta name="assert" content="The clip-path property takes the basic shape
|
||||||
|
'shape()' for clipping. Test the usage of the reference box. On pass you
|
||||||
|
should see a green square.">
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
#rect {
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 10px solid red;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: green;
|
||||||
|
/* The size of the content-box is 100x100. */
|
||||||
|
clip-path: shape(from -10px -10%,
|
||||||
|
hline by 80px, vline by 80%, hline by -80%, close)
|
||||||
|
content-box;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<p>The test passes if there are a green filled rect.</p>
|
||||||
|
<div id="rect"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -5,18 +5,14 @@
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
div {
|
#ref {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
|
||||||
#ref {
|
|
||||||
background-color: green;
|
background-color: green;
|
||||||
clip-path: path(nonzero, "M 10 10, Q 40 0 60 20, T 90 0, c 10 40 20 20 -20 60, s -10 70 -40 -10");
|
clip-path: path(nonzero, "M 10 10 Q 40 0 60 20 T 90 0 c 10 40 20 20 -20 60 s -10 70 -40 -10");
|
||||||
position: absolute;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<p>You should see no red.</p>
|
|
||||||
<div id="ref"></div>
|
<div id="ref"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,18 +5,14 @@
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
|
||||||
</head>
|
</head>
|
||||||
<style>
|
<style>
|
||||||
div {
|
#ref {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
|
||||||
#ref {
|
|
||||||
background-color: green;
|
background-color: green;
|
||||||
clip-path: path(nonzero, "M 20 20 A 25 12 0 0 1 80 20, a 33 33 120 1 1 -40 50, A 20 25 0 0 0 20 20");
|
clip-path: path(nonzero, "M 20 20 A 25 12 0 0 1 80 20 a 33 33 120 1 1 -40 50 A 20 25 0 0 0 20 20");
|
||||||
position: absolute;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<p>You should see no red.</p>
|
|
||||||
<div id="ref"></div>
|
<div id="ref"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче