diff --git a/devtools/server/actors/animation-type-longhand.js b/devtools/server/actors/animation-type-longhand.js index 66d9cfda1dd6..58df958dc45b 100644 --- a/devtools/server/actors/animation-type-longhand.js +++ b/devtools/server/actors/animation-type-longhand.js @@ -210,7 +210,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [ "min-block-size", "-moz-min-font-size-ratio", "min-inline-size", - "offset-path", "padding-block-end", "padding-block-start", "padding-inline-end", diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index 50499051695b..0312775a542b 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -2949,7 +2949,6 @@ exports.CSS_PROPERTIES = { "rotate", "scale", "translate", - "offset-path", "scroll-behavior", "scroll-snap-type-x", "scroll-snap-type-y", @@ -7416,20 +7415,6 @@ exports.CSS_PROPERTIES = { "unset" ] }, - "offset-path": { - "isInherited": false, - "subproperties": [ - "offset-path" - ], - "supports": [], - "values": [ - "inherit", - "initial", - "none", - "path", - "unset" - ] - }, "opacity": { "isInherited": false, "subproperties": [ @@ -9346,10 +9331,6 @@ exports.PREFERENCES = [ "font-variation-settings", "layout.css.font-variations.enabled" ], - [ - "offset-path", - "layout.css.motion-path.enabled" - ], [ "rotate", "layout.css.individual-transform.enabled" diff --git a/dom/svg/SVGPathData.cpp b/dom/svg/SVGPathData.cpp index c56182400494..85a14bbbb8f6 100644 --- a/dom/svg/SVGPathData.cpp +++ b/dom/svg/SVGPathData.cpp @@ -26,41 +26,12 @@ using namespace mozilla; using namespace mozilla::dom::SVGPathSeg_Binding; using namespace mozilla::gfx; -static inline bool IsMoveto(uint16_t aSegType) +static bool IsMoveto(uint16_t aSegType) { return aSegType == PATHSEG_MOVETO_ABS || aSegType == PATHSEG_MOVETO_REL; } -static inline bool -IsMoveto(StylePathCommand::Tag aSegType) -{ - return aSegType == StylePathCommand::Tag::MoveTo; -} - -static inline bool -IsValidType(uint16_t aSegType) -{ - return SVGPathSegUtils::IsValidType(aSegType); -} - -static inline bool -IsValidType(StylePathCommand::Tag aSegType) -{ - return aSegType != StylePathCommand::Tag::Unknown; -} - -static inline bool -IsClosePath(uint16_t aSegType) { - return aSegType == PATHSEG_CLOSEPATH; -} - -static inline bool -IsClosePath(StylePathCommand::Tag aSegType) -{ - return aSegType == StylePathCommand::Tag::ClosePath; -} - nsresult SVGPathData::CopyFrom(const SVGPathData& rhs) { @@ -291,18 +262,18 @@ ApproximateZeroLengthSubpathSquareCaps(PathBuilder* aPB, aPB->MoveTo(aPoint); } -#define MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT \ - do { \ - if (!subpathHasLength && hasLineCaps && aStrokeWidth > 0 && \ - subpathContainsNonMoveTo && \ - IsValidType(prevSegType) && \ - (!IsMoveto(prevSegType) || IsClosePath(segType))) { \ - ApproximateZeroLengthSubpathSquareCaps(aBuilder, segStart, aStrokeWidth);\ - } \ +#define MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT \ + do { \ + if (!subpathHasLength && hasLineCaps && aStrokeWidth > 0 && \ + subpathContainsNonMoveTo && \ + SVGPathSegUtils::IsValidType(prevSegType) && \ + (!IsMoveto(prevSegType) || segType == PATHSEG_CLOSEPATH)) { \ + ApproximateZeroLengthSubpathSquareCaps(builder, segStart, aStrokeWidth);\ + } \ } while(0) already_AddRefed -SVGPathData::BuildPath(PathBuilder* aBuilder, +SVGPathData::BuildPath(PathBuilder* builder, uint8_t aStrokeLineCap, Float aStrokeWidth) const { @@ -338,20 +309,20 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, subpathContainsNonMoveTo = true; MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; segEnd = pathStart; - aBuilder->Close(); + builder->Close(); break; case PATHSEG_MOVETO_ABS: MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; pathStart = segEnd = Point(mData[i], mData[i+1]); - aBuilder->MoveTo(segEnd); + builder->MoveTo(segEnd); subpathHasLength = false; break; case PATHSEG_MOVETO_REL: MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; pathStart = segEnd = segStart + Point(mData[i], mData[i+1]); - aBuilder->MoveTo(segEnd); + builder->MoveTo(segEnd); subpathHasLength = false; break; @@ -359,7 +330,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = Point(mData[i], mData[i+1]); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -367,7 +338,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = segStart + Point(mData[i], mData[i+1]); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -377,7 +348,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = Point(mData[i+4], mData[i+5]); if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); + builder->BezierTo(cp1, cp2, segEnd); } break; @@ -387,7 +358,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = segStart + Point(mData[i+4], mData[i+5]); if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); + builder->BezierTo(cp1, cp2, segEnd); } break; @@ -399,7 +370,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, tcp2 = cp1 + (segEnd - cp1) / 3; if (segEnd != segStart || segEnd != cp1) { subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); + builder->BezierTo(tcp1, tcp2, segEnd); } break; @@ -411,7 +382,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, tcp2 = cp1 + (segEnd - cp1) / 3; if (segEnd != segStart || segEnd != cp1) { subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); + builder->BezierTo(tcp1, tcp2, segEnd); } break; @@ -426,12 +397,12 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, if (segEnd != segStart) { subpathHasLength = true; if (radii.x == 0.0f || radii.y == 0.0f) { - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } else { nsSVGArcConverter converter(segStart, segEnd, radii, mData[i+2], mData[i+3] != 0, mData[i+4] != 0); while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) { - aBuilder->BezierTo(cp1, cp2, segEnd); + builder->BezierTo(cp1, cp2, segEnd); } } } @@ -442,7 +413,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = Point(mData[i], segStart.y); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -450,7 +421,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = segStart + Point(mData[i], 0.0f); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -458,7 +429,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = Point(segStart.x, mData[i]); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -466,7 +437,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = segStart + Point(0.0f, mData[i]); if (segEnd != segStart) { subpathHasLength = true; - aBuilder->LineTo(segEnd); + builder->LineTo(segEnd); } break; @@ -476,7 +447,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = Point(mData[i+2], mData[i+3]); if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); + builder->BezierTo(cp1, cp2, segEnd); } break; @@ -486,7 +457,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, segEnd = segStart + Point(mData[i+2], mData[i+3]); if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); + builder->BezierTo(cp1, cp2, segEnd); } break; @@ -498,7 +469,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, tcp2 = cp1 + (segEnd - cp1) / 3; if (segEnd != segStart || segEnd != cp1) { subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); + builder->BezierTo(tcp1, tcp2, segEnd); } break; @@ -510,7 +481,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, tcp2 = cp1 + (segEnd - cp1) / 3; if (segEnd != segStart || segEnd != cp1) { subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); + builder->BezierTo(tcp1, tcp2, segEnd); } break; @@ -532,7 +503,7 @@ SVGPathData::BuildPath(PathBuilder* aBuilder, MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; - return aBuilder->Finish(); + return builder->Finish(); } already_AddRefed @@ -553,209 +524,6 @@ SVGPathData::BuildPathForMeasuring() const return BuildPath(builder, NS_STYLE_STROKE_LINECAP_BUTT, 0); } -// 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 */ already_AddRefed -SVGPathData::BuildPath(const nsTArray& aPath, - PathBuilder* aBuilder, - uint8_t aStrokeLineCap, - Float aStrokeWidth) -{ - if (aPath.IsEmpty() || !aPath[0].IsMoveTo()) { - return nullptr; // paths without an initial moveto are invalid - } - - auto toGfxPoint = [](const StyleCoordPair& aPair) { - return Point(aPair._0, aPair._1); - }; - - auto isCubicType = [](StylePathCommand::Tag aType) { - return aType == StylePathCommand::Tag::CurveTo || - aType == StylePathCommand::Tag::SmoothCurveTo; - }; - - auto isQuadraticType = [](StylePathCommand::Tag aType) { - return aType == StylePathCommand::Tag::QuadBezierCurveTo || - aType == StylePathCommand::Tag::SmoothQuadBezierCurveTo; - }; - - bool hasLineCaps = aStrokeLineCap != NS_STYLE_STROKE_LINECAP_BUTT; - bool subpathHasLength = false; // visual length - bool subpathContainsNonMoveTo = false; - - StylePathCommand::Tag segType = StylePathCommand::Tag::Unknown; - StylePathCommand::Tag prevSegType = StylePathCommand::Tag::Unknown; - Point pathStart(0.0, 0.0); // start point of [sub]path - Point segStart(0.0, 0.0); - Point segEnd; - Point cp1, cp2; // previous bezier's control points - Point tcp1, tcp2; // temporaries - - // Regarding cp1 and cp2: If the previous segment was a cubic bezier curve, - // then cp2 is its second control point. If the previous segment was a - // quadratic curve, then cp1 is its (only) control point. - - for (const StylePathCommand& cmd: aPath) { - segType = cmd.tag; - switch (segType) { - case StylePathCommand::Tag::ClosePath: - // set this early to allow drawing of square caps for "M{x},{y} Z": - subpathContainsNonMoveTo = true; - MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; - segEnd = pathStart; - aBuilder->Close(); - break; - case StylePathCommand::Tag::MoveTo: { - MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; - const Point& p = toGfxPoint(cmd.move_to.point); - pathStart = segEnd = cmd.move_to.absolute ? p : segStart + p; - aBuilder->MoveTo(segEnd); - subpathHasLength = false; - break; - } - case StylePathCommand::Tag::LineTo: { - const Point& p = toGfxPoint(cmd.line_to.point); - segEnd = cmd.line_to.absolute ? p : segStart + p; - if (segEnd != segStart) { - subpathHasLength = true; - aBuilder->LineTo(segEnd); - } - break; - } - case StylePathCommand::Tag::CurveTo: - cp1 = toGfxPoint(cmd.curve_to.control1); - cp2 = toGfxPoint(cmd.curve_to.control2); - segEnd = toGfxPoint(cmd.curve_to.point); - - if (!cmd.curve_to.absolute) { - cp1 += segStart; - cp2 += segStart; - segEnd += segStart; - } - - if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { - subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); - } - break; - - case StylePathCommand::Tag::QuadBezierCurveTo: - cp1 = toGfxPoint(cmd.quad_bezier_curve_to.control1); - segEnd = toGfxPoint(cmd.quad_bezier_curve_to.point); - - if (!cmd.quad_bezier_curve_to.absolute) { - cp1 += segStart; - segEnd += segStart; // set before setting tcp2! - } - - // Convert quadratic curve to cubic curve: - tcp1 = segStart + (cp1 - segStart) * 2 / 3; - tcp2 = cp1 + (segEnd - cp1) / 3; - - if (segEnd != segStart || segEnd != cp1) { - subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); - } - break; - - case StylePathCommand::Tag::EllipticalArc: { - const auto& arc = cmd.elliptical_arc; - Point radii(arc.rx, arc.ry); - segEnd = toGfxPoint(arc.point); - if (!arc.absolute) { - segEnd += segStart; - } - if (segEnd != segStart) { - subpathHasLength = true; - if (radii.x == 0.0f || radii.y == 0.0f) { - aBuilder->LineTo(segEnd); - } else { - nsSVGArcConverter converter(segStart, segEnd, radii, arc.angle, - arc.large_arc_flag, arc.sweep_flag); - while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) { - aBuilder->BezierTo(cp1, cp2, segEnd); - } - } - } - break; - } - case StylePathCommand::Tag::HorizontalLineTo: - if (cmd.horizontal_line_to.absolute) { - segEnd = Point(cmd.horizontal_line_to.x, segStart.y); - } else { - segEnd = segStart + Point(cmd.horizontal_line_to.x, 0.0f); - } - - if (segEnd != segStart) { - subpathHasLength = true; - aBuilder->LineTo(segEnd); - } - break; - - case StylePathCommand::Tag::VerticalLineTo: - if (cmd.vertical_line_to.absolute) { - segEnd = Point(segStart.x, cmd.vertical_line_to.y); - } else { - segEnd = segStart + Point(0.0f, cmd.vertical_line_to.y); - } - - if (segEnd != segStart) { - subpathHasLength = true; - aBuilder->LineTo(segEnd); - } - break; - - case StylePathCommand::Tag::SmoothCurveTo: - cp1 = isCubicType(prevSegType) ? segStart * 2 - cp2 : segStart; - cp2 = toGfxPoint(cmd.smooth_curve_to.control2); - segEnd = toGfxPoint(cmd.smooth_curve_to.point); - - if (!cmd.smooth_curve_to.absolute) { - cp2 += segStart; - segEnd += segStart; - } - - if (segEnd != segStart || segEnd != cp1 || segEnd != cp2) { - subpathHasLength = true; - aBuilder->BezierTo(cp1, cp2, segEnd); - } - break; - - case StylePathCommand::Tag::SmoothQuadBezierCurveTo: { - cp1 = isQuadraticType(prevSegType) ? segStart * 2 - cp1 : segStart; - // Convert quadratic curve to cubic curve: - tcp1 = segStart + (cp1 - segStart) * 2 / 3; - - const Point& p = toGfxPoint(cmd.smooth_quad_bezier_curve_to.point); - // set before setting tcp2! - segEnd = cmd.smooth_quad_bezier_curve_to.absolute ? p : segStart + p; - tcp2 = cp1 + (segEnd - cp1) / 3; - - if (segEnd != segStart || segEnd != cp1) { - subpathHasLength = true; - aBuilder->BezierTo(tcp1, tcp2, segEnd); - } - break; - } - case StylePathCommand::Tag::Unknown: - MOZ_ASSERT_UNREACHABLE("Unacceptable path segment type"); - return nullptr; - } - - subpathContainsNonMoveTo = !IsMoveto(segType); - prevSegType = segType; - segStart = segEnd; - } - - MOZ_ASSERT(prevSegType == segType, - "prevSegType should be left at the final segType"); - - MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS_TO_DT; - - return aBuilder->Finish(); -} - static double AngleOfVector(const Point& aVector) { diff --git a/dom/svg/SVGPathData.h b/dom/svg/SVGPathData.h index 25a2cdb88498..60dffc253333 100644 --- a/dom/svg/SVGPathData.h +++ b/dom/svg/SVGPathData.h @@ -169,16 +169,6 @@ public: already_AddRefed BuildPath(PathBuilder* aBuilder, uint8_t aCapStyle, Float aStrokeWidth) const; - /** - * This function tries to build the path by an array of StylePathCommand, - * which is generated by cbindgen from Rust (see ServoStyleConsts.h). - * Basically, this is a variant of the above BuildPath() functions. - */ - static already_AddRefed - BuildPath(const nsTArray& aPath, - PathBuilder* aBuilder, - uint8_t aCapStyle, - Float aStrokeWidth); const_iterator begin() const { return mData.Elements(); } const_iterator end() const { return mData.Elements() + mData.Length(); } diff --git a/dom/svg/moz.build b/dom/svg/moz.build index 74162ff1131b..6f79fc07d6e3 100644 --- a/dom/svg/moz.build +++ b/dom/svg/moz.build @@ -81,7 +81,6 @@ EXPORTS.mozilla.dom += [ 'SVGMatrix.h', 'SVGMetadataElement.h', 'SVGMPathElement.h', - 'SVGPathData.h', 'SVGPathElement.h', 'SVGPatternElement.h', 'SVGPolygonElement.h', diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index ee9841af61aa..7aae26eca05a 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -76,7 +76,6 @@ #include "mozilla/dom/DOMRect.h" #include "mozilla/dom/DOMStringList.h" #include "mozilla/dom/KeyframeEffect.h" -#include "mozilla/dom/SVGPathData.h" #include "mozilla/layers/APZCCallbackHelper.h" #include "imgIRequest.h" #include "nsIImageLoadingContent.h" @@ -10267,94 +10266,3 @@ nsLayoutUtils::StyleForScrollbar(nsIFrame* aScrollbarPart) // held strongly by the element. return style.get(); } - -static float -ResolveTransformOrigin(const nsStyleCoord& aCoord, - TransformReferenceBox& aRefBox, - TransformReferenceBox::DimensionGetter aGetter) -{ - float result = 0.0; - const float scale = mozilla::AppUnitsPerCSSPixel(); - if (aCoord.GetUnit() == eStyleUnit_Calc) { - const nsStyleCoord::Calc *calc = aCoord.GetCalcValue(); - result = NSAppUnitsToFloatPixels((aRefBox.*aGetter)(), scale) * - calc->mPercent + - NSAppUnitsToFloatPixels(calc->mLength, scale); - } else if (aCoord.GetUnit() == eStyleUnit_Percent) { - result = NSAppUnitsToFloatPixels((aRefBox.*aGetter)(), scale) * - aCoord.GetPercentValue(); - } else { - MOZ_ASSERT(aCoord.GetUnit() == eStyleUnit_Coord, "unexpected unit"); - result = NSAppUnitsToFloatPixels(aCoord.GetCoordValue(), scale); - } - return result; -} - -/* static */ Maybe -nsLayoutUtils::ResolveMotionPath(const nsIFrame* aFrame) -{ - MOZ_ASSERT(aFrame); - - const nsStyleDisplay* display = aFrame->StyleDisplay(); - if (!display->mMotion || !display->mMotion->HasPath()) { - return Nothing(); - } - - const UniquePtr& motion = display->mMotion; - // Bug 1429299 - Implement offset-distance for motion path. For now, we use - // the default value, i.e. 0%. - float distance = 0.0; - float angle = 0.0; - Point point; - if (motion->OffsetPath().GetType() == StyleShapeSourceType::Path) { - // Build the path and compute the point and angle for creating the - // equivalent translate and rotate. - // Here we only need to build a valid path for motion path, so - // using the default values of stroke-width, stoke-linecap, and fill-rule - // is fine for now because what we want is get the point and its normal - // vector along the path, instead of rendering it. - // FIXME: Bug 1484780, we should cache the path to avoid rebuilding it here - // at every restyle. (Caching the path avoids the cost of flattening it - // again each time.) - RefPtr drawTarget = - gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(); - RefPtr builder = - drawTarget->CreatePathBuilder(FillRule::FILL_WINDING); - RefPtr gfxPath = - SVGPathData::BuildPath(motion->OffsetPath().GetPath()->Path(), - builder, - NS_STYLE_STROKE_LINECAP_BUTT, - 0.0); - if (!gfxPath) { - return Nothing(); - } - float pathLength = gfxPath->ComputeLength(); - float computedDistance = distance * pathLength; - Point tangent; - point = gfxPath->ComputePointAtLength(computedDistance, &tangent); - // Bug 1429301 - Implement offset-rotate for motion path. - // After implement offset-rotate, |angle| will be adjusted more. - // For now, the default value of offset-rotate is "auto", so we use the - // directional tangent vector. - angle = atan2(tangent.y, tangent.x); - } else { - // Bug 1480665: Implement ray() function. - NS_WARNING("Unsupported offset-path value"); - } - - // Compute the offset for motion path translate. - // We need to resolve transform-origin here to calculate the correct path - // translate. (i.e. Center transform-origin on the path.) - TransformReferenceBox refBox(aFrame); - Point origin( - ResolveTransformOrigin(display->mTransformOrigin[0], - refBox, - &TransformReferenceBox::Width), - ResolveTransformOrigin(display->mTransformOrigin[1], - refBox, - &TransformReferenceBox::Height) - ); - // Bug 1186329: the translate parameters will be adjusted more after we - // implement offset-position and offset-anchor. - return Some(MotionPathData { point - origin, angle }); -} diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index bfd437dbc298..3f7715911d3c 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -119,11 +119,6 @@ struct DisplayPortMarginsPropertyData { uint32_t mPriority; }; -struct MotionPathData { - gfx::Point mTranslate; - float mRotate; -}; - } // namespace mozilla // For GetDisplayPort @@ -3118,12 +3113,6 @@ public: */ static ComputedStyle* StyleForScrollbar(nsIFrame* aScrollbarPart); - /** - * Generate the motion path transform result. - **/ - static mozilla::Maybe - ResolveMotionPath(const nsIFrame* aFrame); - private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index 34abb4b8db2e..686d9552ad9a 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -2409,10 +2409,6 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have URL source type!"); return; - case StyleShapeSourceType::Path: - MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have Path source type!"); - return; - case StyleShapeSourceType::Image: { float shapeImageThreshold = styleDisplay->mShapeImageThreshold; mShapeInfo = ShapeInfo::CreateImageShape(shapeOutside.GetShapeImage(), diff --git a/layout/painting/ActiveLayerTracker.cpp b/layout/painting/ActiveLayerTracker.cpp index 4d23ac2b6a26..ae2b2d4cc141 100644 --- a/layout/painting/ActiveLayerTracker.cpp +++ b/layout/painting/ActiveLayerTracker.cpp @@ -249,30 +249,22 @@ static void IncrementScaleRestyleCountIfNeeded(nsIFrame* aFrame, LayerActivity* aActivity) { const nsStyleDisplay* display = aFrame->StyleDisplay(); - if (!display->mSpecifiedTransform && - !display->HasIndividualTransform() && - !(display->mMotion && display->mMotion->HasPath())) { + RefPtr transformList = display->GetCombinedTransform(); + if (!transformList) { // The transform was removed. aActivity->mPreviousTransformScale = Nothing(); - IncrementMutationCount( - &aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]); + IncrementMutationCount(&aActivity->mRestyleCounts[LayerActivity::ACTIVITY_SCALE]); return; } // Compute the new scale due to the CSS transform property. bool dummyBool; nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame); - Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms( - display->mIndividualTransform - ? display->mIndividualTransform->mHead - : nullptr, - nsLayoutUtils::ResolveMotionPath(aFrame), - display->mSpecifiedTransform - ? display->mSpecifiedTransform->mHead - : nullptr, - refBox, - AppUnitsPerCSSPixel(), - &dummyBool); + Matrix4x4 transform = + nsStyleTransformMatrix::ReadTransforms(transformList->mHead, + refBox, + AppUnitsPerCSSPixel(), + &dummyBool); Matrix transform2D; if (!transform.Is2D(&transform2D)) { // We don't attempt to handle 3D transforms; just assume the scale changed. diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index f68ad6705ce6..2988ca57c0f4 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -7849,14 +7849,11 @@ nsDisplayTransform::ComputePerspectiveMatrix(const nsIFrame* aFrame, return true; } -nsDisplayTransform::FrameTransformProperties::FrameTransformProperties( - const nsIFrame* aFrame, - float aAppUnitsPerPixel, - const nsRect* aBoundsOverride) +nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame, + float aAppUnitsPerPixel, + const nsRect* aBoundsOverride) : mFrame(aFrame) - , mIndividualTransformList(aFrame->StyleDisplay()->mIndividualTransform) - , mMotion(nsLayoutUtils::ResolveMotionPath(aFrame)) - , mTransformList(aFrame->StyleDisplay()->mSpecifiedTransform) + , mTransformList(aFrame->StyleDisplay()->GetCombinedTransform()) , mToTransformOrigin(GetDeltaToTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride)) { } @@ -7925,16 +7922,10 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp frame && frame->IsSVGTransformed(&svgTransform, &parentsChildrenOnlyTransform); /* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */ - if (aProperties.HasTransform()) { - result = nsStyleTransformMatrix::ReadTransforms( - aProperties.mIndividualTransformList - ? aProperties.mIndividualTransformList->mHead - : nullptr, - aProperties.mMotion, - aProperties.mTransformList - ? aProperties.mTransformList->mHead - : nullptr, - refBox, aAppUnitsPerPixel, &dummyBool); + if (aProperties.mTransformList) { + result = nsStyleTransformMatrix::ReadTransforms(aProperties.mTransformList->mHead, + refBox, aAppUnitsPerPixel, + &dummyBool); } else if (hasSVGTransforms) { // Correct the translation components for zoom: float pixelsPerCSSPx = AppUnitsPerCSSPixel() / diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 1faa5e806627..7012d7353399 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -68,7 +68,6 @@ enum class nsDisplayOwnLayerFlags; namespace mozilla { class FrameLayerBuilder; -struct MotionPathData; namespace layers { class Layer; class ImageLayer; @@ -6578,11 +6577,6 @@ public: FrameTransformProperties(const nsIFrame* aFrame, float aAppUnitsPerPixel, const nsRect* aBoundsOverride); - // This constructor is used on the compositor (for animations). - // Bug 1186329, Bug 1425837, If we want to support compositor animationsf - // or individual transforms and motion path, we may need to update this. - // For now, let mIndividualTransformList and mMotion as nullptr and - // Nothing(). FrameTransformProperties(RefPtr&& aTransformList, const Point3D& aToTransformOrigin) @@ -6591,14 +6585,7 @@ public: , mToTransformOrigin(aToTransformOrigin) {} - bool HasTransform() const - { - return mIndividualTransformList || mTransformList || mMotion.isSome(); - } - const nsIFrame* mFrame; - const RefPtr mIndividualTransformList; - const mozilla::Maybe mMotion; const RefPtr mTransformList; const Point3D mToTransformOrigin; }; diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 7bd727bae2ee..954b2d4a775a 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -1950,35 +1950,6 @@ Gecko_NewShapeImage(mozilla::StyleShapeSource* aShape) aShape->SetShapeImage(MakeUnique()); } -void -Gecko_NewStyleSVGPath(mozilla::StyleShapeSource* aShape) -{ - MOZ_ASSERT(aShape); - aShape->SetPath(MakeUnique()); -} - -void -Gecko_SetStyleMotion(UniquePtr* aMotion, - mozilla::StyleMotion* aValue) -{ - MOZ_ASSERT(aMotion); - aMotion->reset(aValue); -} - -mozilla::StyleMotion* -Gecko_NewStyleMotion() -{ - return new StyleMotion(); -} - -void -Gecko_CopyStyleMotions(mozilla::UniquePtr* aMotion, - const mozilla::StyleMotion* aOther) -{ - MOZ_ASSERT(aMotion); - *aMotion = aOther ? MakeUnique(*aOther) : nullptr; -} - void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len) { diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index 4da68350c022..c195a89cc0e0 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -524,12 +524,6 @@ void Gecko_NewBasicShape(mozilla::StyleShapeSource* shape, mozilla::StyleBasicShapeType type); void Gecko_NewShapeImage(mozilla::StyleShapeSource* shape); void Gecko_StyleShapeSource_SetURLValue(mozilla::StyleShapeSource* shape, mozilla::css::URLValue* uri); -void Gecko_NewStyleSVGPath(mozilla::StyleShapeSource* shape); -void Gecko_SetStyleMotion(mozilla::UniquePtr* aMotion, - mozilla::StyleMotion* aValue); -mozilla::StyleMotion* Gecko_NewStyleMotion(); -void Gecko_CopyStyleMotions(mozilla::UniquePtr* motion, - const mozilla::StyleMotion* other); void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len); void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest); diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index fb8e7828b6bd..665f56468c8e 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -473,7 +473,6 @@ structs-types = [ "mozilla::FontWeight", "mozilla::MallocSizeOf", "mozilla::OriginFlags", - "mozilla::StyleMotion", "mozilla::UniquePtr", "mozilla::StyleDisplayMode", "ServoRawOffsetArc", diff --git a/layout/style/ServoCSSPropList.mako.py b/layout/style/ServoCSSPropList.mako.py index 08438c1590b5..6de1fe1dbe01 100644 --- a/layout/style/ServoCSSPropList.mako.py +++ b/layout/style/ServoCSSPropList.mako.py @@ -94,7 +94,6 @@ SERIALIZED_PREDEFINED_TYPES = [ "NonNegativeLength", "NonNegativeLengthOrPercentage", "ListStyleType", - "OffsetPath", "Opacity", "Resize", "url::ImageUrlOrNone", diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 073a088dcd94..0590e3ea0f1b 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -5048,11 +5048,6 @@ nsComputedDOMStyle::GetShapeSource( SetValueToStyleImage(*aShapeSource.GetShapeImage(), val); return val.forget(); } - case StyleShapeSourceType::Path: { - // Bug 1246764: we have to support this for clip-path. For now, no one - // uses this. - MOZ_ASSERT_UNREACHABLE("Unexpected SVG Path type."); - } } return nullptr; } diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 4b0cdcee9f1e..6af07429d5ef 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -198,7 +198,6 @@ enum class StyleShapeSourceType : uint8_t { Image, // shape-outside only Shape, Box, - Path, // SVG path function }; // -moz-stack-sizing diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index f8f93d7892fb..d82ccd87db8f 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1039,9 +1039,6 @@ StyleShapeSource::operator==(const StyleShapeSource& aOther) const case StyleShapeSourceType::Box: return mReferenceBox == aOther.mReferenceBox; - - case StyleShapeSourceType::Path: - return *mSVGPath == *aOther.mSVGPath; } MOZ_ASSERT_UNREACHABLE("Unexpected shape source type!"); @@ -1093,15 +1090,6 @@ StyleShapeSource::SetBasicShape(UniquePtr aBasicShape, mType = StyleShapeSourceType::Shape; } -void -StyleShapeSource::SetPath(UniquePtr aPath) -{ - MOZ_ASSERT(aPath); - DoDestroy(); - new (&mSVGPath) UniquePtr(std::move(aPath)); - mType = StyleShapeSourceType::Path; -} - void StyleShapeSource::SetReferenceBox(StyleGeometryBox aReferenceBox) { @@ -1135,10 +1123,6 @@ StyleShapeSource::DoCopy(const StyleShapeSource& aOther) case StyleShapeSourceType::Box: SetReferenceBox(aOther.GetReferenceBox()); break; - - case StyleShapeSourceType::Path: - SetPath(MakeUnique(*aOther.GetPath())); - break; } } @@ -1153,9 +1137,6 @@ StyleShapeSource::DoDestroy() case StyleShapeSourceType::URL: mShapeImage.~UniquePtr(); break; - case StyleShapeSourceType::Path: - mSVGPath.~UniquePtr(); - break; case StyleShapeSourceType::None: case StyleShapeSourceType::Box: // Not a union type, so do nothing. @@ -3636,10 +3617,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource) , mSpecifiedRotate(aSource.mSpecifiedRotate) , mSpecifiedTranslate(aSource.mSpecifiedTranslate) , mSpecifiedScale(aSource.mSpecifiedScale) - , mIndividualTransform(aSource.mIndividualTransform) - , mMotion(aSource.mMotion - ? MakeUnique(*aSource.mMotion) - : nullptr) + , mCombinedTransform(aSource.mCombinedTransform) , mTransformOrigin{ aSource.mTransformOrigin[0], aSource.mTransformOrigin[1], aSource.mTransformOrigin[2] } @@ -3704,8 +3682,9 @@ nsStyleDisplay::~nsStyleDisplay() mSpecifiedTranslate); ReleaseSharedListOnMainThread("nsStyleDisplay::mSpecifiedScale", mSpecifiedScale); - ReleaseSharedListOnMainThread("nsStyleDisplay::mIndividualTransform", - mIndividualTransform); + ReleaseSharedListOnMainThread("nsStyleDisplay::mCombinedTransform", + mCombinedTransform); + MOZ_COUNT_DTOR(nsStyleDisplay); } @@ -3733,7 +3712,7 @@ nsStyleDisplay::FinishStyle( } } - GenerateCombinedIndividualTransform(); + GenerateCombinedTransform(); } static inline nsChangeHint @@ -3756,29 +3735,6 @@ CompareTransformValues(const RefPtr& aList, return result; } -static inline nsChangeHint -CompareMotionValues(const StyleMotion* aMotion, - const StyleMotion* aNewMotion) -{ - nsChangeHint result = nsChangeHint(0); - - // TODO: Bug 1482737: This probably doesn't need to UpdateOverflow - // (or UpdateTransformLayer) if there's already a transform. - if (!aMotion != !aNewMotion || - (aMotion && *aMotion != *aNewMotion)) { - // Set the same hints as what we use for transform because motion path is - // a kind of transform and will be combined with other transforms. - result |= nsChangeHint_UpdateTransformLayer; - if ((aMotion && aMotion->HasPath()) && - (aNewMotion && aNewMotion->HasPath())) { - result |= nsChangeHint_UpdatePostTransformOverflow; - } else { - result |= nsChangeHint_UpdateOverflow; - } - } - return result; -} - nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const { @@ -3910,7 +3866,6 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const aNewData.mSpecifiedTranslate); transformHint |= CompareTransformValues(mSpecifiedScale, aNewData.mSpecifiedScale); - transformHint |= CompareMotionValues(mMotion.get(), aNewData.mMotion.get()); const nsChangeHint kUpdateOverflowAndRepaintHint = nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame; @@ -4030,17 +3985,17 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const } void -nsStyleDisplay::GenerateCombinedIndividualTransform() +nsStyleDisplay::GenerateCombinedTransform() { // FIXME(emilio): This should probably be called from somewhere like what we // do for image layers, instead of FinishStyle. // // This does and undoes the work a ton of times in Stylo. - mIndividualTransform = nullptr; + mCombinedTransform = nullptr; // Follow the order defined in the spec to append transform functions. // https://drafts.csswg.org/css-transforms-2/#ctm - AutoTArray shareLists; + AutoTArray shareLists; if (mSpecifiedTranslate) { shareLists.AppendElement(mSpecifiedTranslate.get()); } @@ -4050,20 +4005,24 @@ nsStyleDisplay::GenerateCombinedIndividualTransform() if (mSpecifiedScale) { shareLists.AppendElement(mSpecifiedScale.get()); } + if (mSpecifiedTransform) { + shareLists.AppendElement(mSpecifiedTransform.get()); + } if (shareLists.Length() == 0) { return; } + if (shareLists.Length() == 1) { - mIndividualTransform = shareLists[0]; + mCombinedTransform = shareLists[0]; return; } - // In common, we may have 3 transform functions: - // 1. one rotate function in mSpecifiedRotate, - // 2. one translate function in mSpecifiedTranslate, - // 3. one scale function in mSpecifiedScale. - AutoTArray valueLists; + // In common, we may have 3 transform functions(for rotate, translate and + // scale) in mSpecifiedTransform, one rotate function in mSpecifiedRotate, + // one translate function in mSpecifiedTranslate, and one scale function in + // mSpecifiedScale. So 6 slots are enough for the most cases. + AutoTArray valueLists; for (auto list: shareLists) { if (list) { valueLists.AppendElement(list->mHead->Clone()); @@ -4078,9 +4037,8 @@ nsStyleDisplay::GenerateCombinedIndividualTransform() valueLists[i]->mNext = valueLists[i + 1]; } - mIndividualTransform = new nsCSSValueSharedList(valueLists[0]); + mCombinedTransform = new nsCSSValueSharedList(valueLists[0]); } - // -------------------- // nsStyleVisibility // diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index d1c7b8142cce..2b3c8787d0c4 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1971,27 +1971,6 @@ private: nsStyleCorners mRadius; }; -struct StyleSVGPath final -{ - const nsTArray& Path() const - { - return mPath; - } - - bool operator==(const StyleSVGPath& aOther) const - { - return mPath == aOther.mPath; - } - - bool operator!=(const StyleSVGPath& aOther) const - { - return !(*this == aOther); - } - -private: - nsTArray mPath; -}; - struct StyleShapeSource final { StyleShapeSource(); @@ -2056,13 +2035,6 @@ struct StyleShapeSource final void SetReferenceBox(StyleGeometryBox aReferenceBox); - const StyleSVGPath* GetPath() const - { - MOZ_ASSERT(mType == StyleShapeSourceType::Path, "Wrong shape source type!"); - return mSVGPath.get(); - } - void SetPath(UniquePtr aPath); - private: void* operator new(size_t) = delete; @@ -2072,41 +2044,13 @@ private: union { mozilla::UniquePtr mBasicShape; mozilla::UniquePtr mShapeImage; - mozilla::UniquePtr mSVGPath; + // TODO: Bug 1429298, implement SVG Path function. // TODO: Bug 1480665, implement ray() function. }; StyleShapeSourceType mType = StyleShapeSourceType::None; StyleGeometryBox mReferenceBox = StyleGeometryBox::NoBox; }; -struct StyleMotion final -{ - bool operator==(const StyleMotion& aOther) const - { - return mOffsetPath == aOther.mOffsetPath; - } - - bool operator!=(const StyleMotion& aOther) const - { - return !(*this == aOther); - } - - const StyleShapeSource& OffsetPath() const - { - return mOffsetPath; - } - - bool HasPath() const - { - // Bug 1186329: We have to check other acceptable types after supporting - // different values of offset-path. e.g. basic-shapes, ray. - return mOffsetPath.GetType() == StyleShapeSourceType::Path; - } - -private: - StyleShapeSource mOffsetPath; -}; - } // namespace mozilla struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay @@ -2181,10 +2125,12 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay RefPtr mSpecifiedRotate; RefPtr mSpecifiedTranslate; RefPtr mSpecifiedScale; - // Used to store the final combination of mSpecifiedRotate, - // mSpecifiedTranslate, and mSpecifiedScale. - RefPtr mIndividualTransform; - mozilla::UniquePtr mMotion; + + // Used to store the final combination of mSpecifiedTranslate, + // mSpecifiedRotate, mSpecifiedScale and mSpecifiedTransform. + // Use GetCombinedTransform() to get the final transform, instead of + // accessing mCombinedTransform directly. + RefPtr mCombinedTransform; nsStyleCoord mTransformOrigin[3]; // percent, coord, calc, 3rd param is coord, calc only nsStyleCoord mChildPerspective; // none, coord @@ -2434,8 +2380,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay return mSpecifiedTransform || mSpecifiedRotate || mSpecifiedTranslate || mSpecifiedScale || mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || - (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM) || - (mMotion && mMotion->HasPath()); + (mWillChangeBitField & NS_STYLE_WILL_CHANGE_TRANSFORM); } bool HasIndividualTransform() const { @@ -2525,17 +2470,21 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const; /** - * Returns the final combined individual transform. + * Returns the final combined transform. **/ - already_AddRefed GetCombinedTransform() const - { - return mIndividualTransform ? do_AddRef(mIndividualTransform) : nullptr; + already_AddRefed GetCombinedTransform() const { + if (mCombinedTransform) { + return do_AddRef(mCombinedTransform); + } + + // backward compatible to gecko-backed style system. + return mSpecifiedTransform ? do_AddRef(mSpecifiedTransform) : nullptr; } private: // Helpers for above functions, which do some but not all of the tests // for them (since transform must be tested separately for each). - void GenerateCombinedIndividualTransform(); + void GenerateCombinedTransform(); }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp index 8b6ed4b18d9e..fe67064f40ad 100644 --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -926,12 +926,14 @@ SetIdentityMatrix(nsCSSValue::Array* aMatrix) } } -static void -ReadTransformsImpl(Matrix4x4& aMatrix, - const nsCSSValueList* aList, - TransformReferenceBox& aRefBox, - bool* aContains3dTransform) +Matrix4x4 +ReadTransforms(const nsCSSValueList* aList, + TransformReferenceBox& aRefBox, + float aAppUnitsPerMatrixUnit, + bool* aContains3dTransform) { + Matrix4x4 result; + for (const nsCSSValueList* curr = aList; curr != nullptr; curr = curr->mNext) { const nsCSSValue &currElem = curr->mValue; if (currElem.GetUnit() != eCSSUnit_Function) { @@ -945,55 +947,9 @@ ReadTransformsImpl(Matrix4x4& aMatrix, "Incoming function is too short!"); /* Read in a single transform matrix. */ - MatrixForTransformFunction(aMatrix, currElem.GetArrayValue(), aRefBox, + MatrixForTransformFunction(result, currElem.GetArrayValue(), aRefBox, aContains3dTransform); } -} - -Matrix4x4 -ReadTransforms(const nsCSSValueList* aList, - TransformReferenceBox& aRefBox, - float aAppUnitsPerMatrixUnit, - bool* aContains3dTransform) -{ - Matrix4x4 result; - ReadTransformsImpl(result, aList, aRefBox, aContains3dTransform); - - float scale = float(AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit; - result.PreScale(1/scale, 1/scale, 1/scale); - result.PostScale(scale, scale, scale); - - return result; -} - -Matrix4x4 -ReadTransforms(const nsCSSValueList* aIndividualTransforms, - const Maybe& aMotion, - const nsCSSValueList* aTransform, - TransformReferenceBox& aRefBox, - float aAppUnitsPerMatrixUnit, - bool* aContains3dTransform) -{ - Matrix4x4 result; - - if (aIndividualTransforms) { - ReadTransformsImpl(result, aIndividualTransforms, aRefBox, - aContains3dTransform); - } - - if (aMotion.isSome()) { - // Create the equivalent translate and rotate function, according to the - // order in spec. We combine the translate and then the rotate. - // https://drafts.fxtf.org/motion-1/#calculating-path-transform - result.PreTranslate(aMotion->mTranslate.x, aMotion->mTranslate.y, 0.0); - if (aMotion->mRotate != 0.0) { - result.RotateZ(aMotion->mRotate); - } - } - - if (aTransform) { - ReadTransformsImpl(result, aTransform, aRefBox, aContains3dTransform); - } float scale = float(AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit; result.PreScale(1/scale, 1/scale, 1/scale); diff --git a/layout/style/nsStyleTransformMatrix.h b/layout/style/nsStyleTransformMatrix.h index 3cc88f8b0393..cbe0cf2bcc86 100644 --- a/layout/style/nsStyleTransformMatrix.h +++ b/layout/style/nsStyleTransformMatrix.h @@ -24,10 +24,6 @@ class nsPresContext; struct gfxQuaternion; struct nsRect; -namespace mozilla { -struct MotionPathData; -} - /** * A helper to generate gfxMatrixes from css transform functions. */ @@ -204,16 +200,6 @@ namespace nsStyleTransformMatrix { float aAppUnitsPerMatrixUnit, bool* aContains3dTransform); - // Generate the gfx::Matrix for CSS Transform Module Level 2. - // https://drafts.csswg.org/css-transforms-2/#ctm - mozilla::gfx::Matrix4x4 - ReadTransforms(const nsCSSValueList* aIndividualTransforms, - const mozilla::Maybe& aMotion, - const nsCSSValueList* aTransform, - TransformReferenceBox& aRefBox, - float aAppUnitsPerMatrixUnit, - bool* aContains3dTransform); - /** * Given two nsStyleCoord values, compute the 2d position with respect to the * given TransformReferenceBox that these values describe, in device pixels. diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index e38f81cf8e9a..9d9a7519536b 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -8173,28 +8173,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.scrollbar-width.enabled")) { }; } -if (IsCSSPropertyPrefEnabled("layout.css.motion-path.enabled")) { - gCSSProperties["offset-path"] = { - domProp: "offsetPath", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "none" ], - other_values: [ - "path('M 10 10 20 20 H 90 V 90 Z')", - "path('M10 10 20,20H90V90Z')", - "path('M 10 10 C 20 20, 40 20, 50 10')", - "path('M 10 80 C 40 10, 65 10, 95 80 S 1.5e2 150, 180 80')", - "path('M 10 80 Q 95 10 180 80')", - "path('M 10 80 Q 52.5 10, 95 80 T 180 80')", - "path('M 80 80 A 45 45, 0, 0, 0, 1.25e2 1.25e2 L 125 80 Z')", - "path('M100-200h20z')", - "path('M10,10L20.6.5z')" - ], - invalid_values: [ "path('')", "path()", "path(a)", "path('M 10 Z')" , - "path('M 10-10 20')", "path('M 10 10 C 20 20 40 20')" ] - }; -} - const OVERFLOW_MOZKWS = [ "-moz-scrollbars-none", "-moz-scrollbars-horizontal", diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 223a1b10a34f..1bb5deed4df1 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3073,13 +3073,6 @@ pref("layout.css.ruby.intercharacter.enabled", false); // Is support for overscroll-behavior enabled? pref("layout.css.overscroll-behavior.enabled", true); -// Is support for motion-path enabled? -#ifdef RELEASE_OR_BETA -pref("layout.css.motion-path.enabled", false); -#else -pref("layout.css.motion-path.enabled", true); -#endif - // pref for which side vertical scrollbars should be on // 0 = end-side in UI direction // 1 = end-side in document/content direction diff --git a/servo/components/style/cbindgen.toml b/servo/components/style/cbindgen.toml index c0eeee9b968a..5a0e5e19ea74 100644 --- a/servo/components/style/cbindgen.toml +++ b/servo/components/style/cbindgen.toml @@ -7,7 +7,6 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi * a. Alternatively, you can clone `https://github.com/eqrion/cbindgen` and use a tagged release * 2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate style -o layout/style/ServoStyleConsts.h` */""" -include_guard = "mozilla_ServoStyleConsts_h" include_version = true braces = "SameLine" line_length = 80 @@ -23,5 +22,5 @@ derive_helper_methods = true [export] prefix = "Style" -include = ["StyleDisplay", "StyleAppearance", "StyleDisplayMode", "StylePathCommand"] -item_types = ["enums", "structs", "typedefs"] +include = ["StyleDisplay", "StyleAppearance", "StyleDisplayMode"] +item_types = ["enums"] diff --git a/servo/components/style/gecko/conversions.rs b/servo/components/style/gecko/conversions.rs index 154ad95bc439..3b1f31a1b08d 100644 --- a/servo/components/style/gecko/conversions.rs +++ b/servo/components/style/gecko/conversions.rs @@ -638,7 +638,6 @@ pub mod basic_shape { use values::computed::basic_shape::{BasicShape, ClippingShape, FloatAreaShape, ShapeRadius}; use values::computed::border::{BorderCornerRadius, BorderRadius}; use values::computed::length::LengthOrPercentage; - use values::computed::motion::OffsetPath; use values::computed::position; use values::computed::url::ComputedUrl; use values::generics::basic_shape::{BasicShape as GenericBasicShape, InsetRect, Polygon}; @@ -670,7 +669,6 @@ pub mod basic_shape { Some(ShapeSource::Shape(shape, reference_box)) }, StyleShapeSourceType::URL | StyleShapeSourceType::Image => None, - StyleShapeSourceType::Path => None, } } } @@ -712,29 +710,6 @@ pub mod basic_shape { } } - impl<'a> From<&'a StyleShapeSource> for OffsetPath { - fn from(other: &'a StyleShapeSource) -> Self { - use gecko_bindings::structs::StylePathCommand; - use values::specified::motion::{SVGPathData, PathCommand}; - match other.mType { - StyleShapeSourceType::Path => { - let gecko_path = unsafe { &*other.__bindgen_anon_1.mSVGPath.as_ref().mPtr }; - let result: Vec = - gecko_path.mPath.iter().map(|gecko: &StylePathCommand| { - // unsafe: cbindgen ensures the representation is the same. - unsafe{ ::std::mem::transmute(*gecko) } - }).collect(); - OffsetPath::Path(SVGPathData::new(result.into_boxed_slice())) - }, - StyleShapeSourceType::None => OffsetPath::none(), - StyleShapeSourceType::Shape | - StyleShapeSourceType::Box | - StyleShapeSourceType::URL | - StyleShapeSourceType::Image => unreachable!("Unsupported offset-path type"), - } - } - } - impl<'a> From<&'a StyleBasicShape> for BasicShape { fn from(other: &'a StyleBasicShape) -> Self { match other.mType { diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 596dc29fb19b..33a66498b2d9 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -3053,7 +3053,7 @@ fn static_assert() { scroll-snap-points-x scroll-snap-points-y scroll-snap-type-x scroll-snap-type-y scroll-snap-coordinate perspective-origin -moz-binding will-change - offset-path overscroll-behavior-x overscroll-behavior-y + overscroll-behavior-x overscroll-behavior-y overflow-clip-box-inline overflow-clip-box-block perspective-origin -moz-binding will-change shape-outside contain touch-action translate @@ -3681,51 +3681,6 @@ fn static_assert() { ${impl_simple_copy("contain", "mContain")} ${impl_simple_type_with_conversion("touch_action")} - - pub fn set_offset_path(&mut self, v: longhands::offset_path::computed_value::T) { - use gecko_bindings::bindings::{Gecko_NewStyleMotion, Gecko_NewStyleSVGPath}; - use gecko_bindings::bindings::Gecko_SetStyleMotion; - use gecko_bindings::structs::StyleShapeSourceType; - use values::specified::OffsetPath; - - let motion = unsafe { Gecko_NewStyleMotion().as_mut().unwrap() }; - match v { - OffsetPath::None => motion.mOffsetPath.mType = StyleShapeSourceType::None, - OffsetPath::Path(servo_path) => { - motion.mOffsetPath.mType = StyleShapeSourceType::Path; - let gecko_path = unsafe { - let ref mut source = motion.mOffsetPath; - Gecko_NewStyleSVGPath(source); - &mut source.__bindgen_anon_1.mSVGPath.as_mut().mPtr.as_mut().unwrap().mPath - }; - unsafe { gecko_path.set_len(servo_path.commands().len() as u32) }; - debug_assert_eq!(gecko_path.len(), servo_path.commands().len()); - for (servo, gecko) in servo_path.commands().iter().zip(gecko_path.iter_mut()) { - // unsafe: cbindgen ensures the representation is the same. - *gecko = unsafe { transmute(*servo) }; - } - }, - } - unsafe { Gecko_SetStyleMotion(&mut self.gecko.mMotion, motion) }; - } - - pub fn clone_offset_path(&self) -> longhands::offset_path::computed_value::T { - use values::specified::OffsetPath; - match unsafe { self.gecko.mMotion.mPtr.as_ref() } { - None => OffsetPath::none(), - Some(v) => (&v.mOffsetPath).into() - } - } - - pub fn copy_offset_path_from(&mut self, other: &Self) { - use gecko_bindings::bindings::Gecko_CopyStyleMotions; - unsafe { Gecko_CopyStyleMotions(&mut self.gecko.mMotion, other.gecko.mMotion.mPtr) }; - } - - pub fn reset_offset_path(&mut self, other: &Self) { - self.copy_offset_path_from(other); - } - <%def name="simple_image_array_property(name, shorthand, field_name)"> diff --git a/servo/components/style/properties/longhands/box.mako.rs b/servo/components/style/properties/longhands/box.mako.rs index 4ef45a502bcc..6b6bcf9cbe3f 100644 --- a/servo/components/style/properties/longhands/box.mako.rs +++ b/servo/components/style/properties/longhands/box.mako.rs @@ -356,17 +356,6 @@ ${helpers.predefined_type( servo_restyle_damage="reflow_out_of_flow" )} -// Motion Path Module Level 1 -${helpers.predefined_type( - "offset-path", - "OffsetPath", - "computed::OffsetPath::none()", - animation_value_type="none", - gecko_pref="layout.css.motion-path.enabled", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", - spec="https://drafts.fxtf.org/motion-1/#offset-path-property" -)} - // CSSOM View Module // https://www.w3.org/TR/cssom-view-1/ ${helpers.single_keyword("scroll-behavior", diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index d8cc938c1f3c..9a6b5fd76b58 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -65,7 +65,6 @@ pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercent pub use self::list::Quotes; #[cfg(feature = "gecko")] pub use self::list::ListStyleType; -pub use self::motion::OffsetPath; pub use self::outline::OutlineStyle; pub use self::percentage::{Percentage, NonNegativePercentage}; pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex}; @@ -101,7 +100,6 @@ pub mod gecko; pub mod image; pub mod length; pub mod list; -pub mod motion; pub mod outline; pub mod percentage; pub mod position; diff --git a/servo/components/style/values/computed/motion.rs b/servo/components/style/values/computed/motion.rs deleted file mode 100644 index 935ba57f8453..000000000000 --- a/servo/components/style/values/computed/motion.rs +++ /dev/null @@ -1,10 +0,0 @@ -/* 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/. */ - -//! Computed types for CSS values that are related to motion path. - -/// A computed offset-path. The computed value is as specified value. -/// -/// https://drafts.fxtf.org/motion-1/#offset-path-property -pub use values::specified::motion::OffsetPath as OffsetPath; diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs index 1bd52e916d07..2da4c7e93d3e 100644 --- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -58,7 +58,6 @@ pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercent pub use self::list::Quotes; #[cfg(feature = "gecko")] pub use self::list::ListStyleType; -pub use self::motion::OffsetPath; pub use self::outline::OutlineStyle; pub use self::rect::LengthOrNumberRect; pub use self::resolution::Resolution; @@ -102,7 +101,6 @@ pub mod image; pub mod length; pub mod list; pub mod outline; -pub mod motion; pub mod percentage; pub mod position; pub mod rect; diff --git a/servo/components/style/values/specified/motion.rs b/servo/components/style/values/specified/motion.rs deleted file mode 100644 index ffaaf7cff17b..000000000000 --- a/servo/components/style/values/specified/motion.rs +++ /dev/null @@ -1,558 +0,0 @@ -/* 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/. */ - -//! Specified types for CSS values that are related to motion path. - -use cssparser::Parser; -use parser::{Parse, ParserContext}; -use std::fmt::{self, Write}; -use std::iter::Peekable; -use std::str::Chars; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; -use style_traits::values::SequenceWriter; -use values::CSSFloat; - -/// The offset-path value. -/// -/// https://drafts.fxtf.org/motion-1/#offset-path-property -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] -pub enum OffsetPath { - // We could merge SVGPathData into ShapeSource, so we could reuse them. However, - // we don't want to support other value for offset-path, so use SVGPathData only for now. - /// Path value for path(). - #[css(function)] - Path(SVGPathData), - /// None value. - None, - // Bug 1186329: Implement ray(), , , and . -} - -impl OffsetPath { - /// Return None. - #[inline] - pub fn none() -> Self { - OffsetPath::None - } -} - -impl Parse for OffsetPath { - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't> - ) -> Result> { - // Parse none. - if input.try(|i| i.expect_ident_matching("none")).is_ok() { - return Ok(OffsetPath::none()); - } - - // Parse possible functions. - let location = input.current_source_location(); - let function = input.expect_function()?.clone(); - input.parse_nested_block(move |i| { - match_ignore_ascii_case! { &function, - // Bug 1186329: Implement the parser for ray(), , , - // and . - "path" => SVGPathData::parse(context, i).map(OffsetPath::Path), - _ => { - Err(location.new_custom_error( - StyleParseErrorKind::UnexpectedFunction(function.clone()) - )) - }, - } - }) - } -} - -/// SVG Path parser. -struct PathParser<'a> { - chars: Peekable>, - path: Vec, -} - -macro_rules! parse_arguments { - ( - $parser:ident, - $abs:ident, - $enum:ident, - [ $para:ident => $func:ident $(, $other_para:ident => $other_func:ident)* ] - ) => { - { - loop { - let $para = $func(&mut $parser.chars)?; - $( - skip_comma_wsp(&mut $parser.chars); - let $other_para = $other_func(&mut $parser.chars)?; - )* - $parser.path.push(PathCommand::$enum { $para $(, $other_para)*, $abs }); - - // End of string or the next character is a possible new command. - if !skip_wsp(&mut $parser.chars) || - $parser.chars.peek().map_or(true, |c| c.is_ascii_alphabetic()) { - break; - } - skip_comma_wsp(&mut $parser.chars); - } - Ok(()) - } - } -} - -impl<'a> PathParser<'a> { - /// Parse a sub-path. - fn parse_subpath(&mut self) -> Result<(), ()> { - // Handle "moveto" Command first. If there is no "moveto", this is not a valid sub-path - // (i.e. not a valid moveto-drawto-command-group). - self.parse_moveto()?; - - // Handle other commands. - loop { - skip_wsp(&mut self.chars); - if self.chars.peek().map_or(true, |m| *m == 'M' || *m == 'm') { - break; - } - - match self.chars.next() { - Some(command) => { - let abs = command.is_uppercase(); - macro_rules! parse_command { - ( $($($p:pat)|+ => $parse_func:ident,)* ) => { - match command { - $( - $($p)|+ => { - skip_wsp(&mut self.chars); - self.$parse_func(abs)?; - }, - )* - _ => return Err(()), - } - } - } - parse_command!( - 'Z' | 'z' => parse_closepath, - 'L' | 'l' => parse_lineto, - 'H' | 'h' => parse_h_lineto, - 'V' | 'v' => parse_v_lineto, - 'C' | 'c' => parse_curveto, - 'S' | 's' => parse_smooth_curveto, - 'Q' | 'q' => parse_quadratic_bezier_curveto, - 'T' | 't' => parse_smooth_quadratic_bezier_curveto, - 'A' | 'a' => parse_elliprical_arc, - ); - }, - _ => break, // no more commands. - } - } - Ok(()) - } - - /// Parse "moveto" command. - fn parse_moveto(&mut self) -> Result<(), ()> { - let command = match self.chars.next() { - Some(c) if c == 'M' || c == 'm' => c, - _ => return Err(()), - }; - - skip_wsp(&mut self.chars); - let point = parse_coord(&mut self.chars)?; - let absolute = command == 'M'; - self.path.push(PathCommand::MoveTo { point, absolute } ); - - // End of string or the next character is a possible new command. - if !skip_wsp(&mut self.chars) || - self.chars.peek().map_or(true, |c| c.is_ascii_alphabetic()) { - return Ok(()); - } - skip_comma_wsp(&mut self.chars); - - // If a moveto is followed by multiple pairs of coordinates, the subsequent - // pairs are treated as implicit lineto commands. - self.parse_lineto(absolute) - } - - /// Parse "closepath" command. - fn parse_closepath(&mut self, _absolute: bool) -> Result<(), ()> { - self.path.push(PathCommand::ClosePath); - Ok(()) - } - - /// Parse "lineto" command. - fn parse_lineto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, LineTo, [ point => parse_coord ]) - } - - /// Parse horizontal "lineto" command. - fn parse_h_lineto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, HorizontalLineTo, [ x => parse_number ]) - } - - /// Parse vertical "lineto" command. - fn parse_v_lineto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, VerticalLineTo, [ y => parse_number ]) - } - - /// Parse cubic Bézier curve command. - fn parse_curveto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, CurveTo, [ - control1 => parse_coord, control2 => parse_coord, point => parse_coord - ]) - } - - /// Parse smooth "curveto" command. - fn parse_smooth_curveto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, SmoothCurveTo, [ - control2 => parse_coord, point => parse_coord - ]) - } - - /// Parse quadratic Bézier curve command. - fn parse_quadratic_bezier_curveto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, QuadBezierCurveTo, [ - control1 => parse_coord, point => parse_coord - ]) - } - - /// Parse smooth quadratic Bézier curveto command. - fn parse_smooth_quadratic_bezier_curveto(&mut self, absolute: bool) -> Result<(), ()> { - parse_arguments!(self, absolute, SmoothQuadBezierCurveTo, [ point => parse_coord ]) - } - - /// Parse elliptical arc curve command. - fn parse_elliprical_arc(&mut self, absolute: bool) -> Result<(), ()> { - // Parse a flag whose value is '0' or '1'; otherwise, return Err(()). - let parse_flag = |iter: &mut Peekable| -> Result { - let value = match iter.peek() { - Some(c) if *c == '0' || *c == '1' => *c == '1', - _ => return Err(()), - }; - iter.next(); - Ok(value) - }; - parse_arguments!(self, absolute, EllipticalArc, [ - rx => parse_number, - ry => parse_number, - angle => parse_number, - large_arc_flag => parse_flag, - sweep_flag => parse_flag, - point => parse_coord - ]) - } -} - -/// The SVG path data. -/// -/// https://www.w3.org/TR/SVG11/paths.html#PathData -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] -pub struct SVGPathData(Box<[PathCommand]>); - -impl SVGPathData { - /// Return SVGPathData by a slice of PathCommand. - #[inline] - pub fn new(cmd: Box<[PathCommand]>) -> Self { - debug_assert!(!cmd.is_empty()); - SVGPathData(cmd) - } - - /// Get the array of PathCommand. - #[inline] - pub fn commands(&self) -> &[PathCommand] { - debug_assert!(!self.0.is_empty()); - &self.0 - } -} - -impl ToCss for SVGPathData { - #[inline] - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write - { - dest.write_char('"')?; - { - let mut writer = SequenceWriter::new(dest, " "); - for command in self.0.iter() { - writer.item(command)?; - } - } - dest.write_char('"') - } -} - -impl Parse for SVGPathData { - // We cannot use cssparser::Parser to parse a SVG path string because the spec wants to make - // the SVG path string as compact as possible. (i.e. The whitespaces may be dropped.) - // e.g. "M100 200L100 200" is a valid SVG path string. If we use tokenizer, the first ident - // is "M100", instead of "M", and this is not correct. Therefore, we use a Peekable - // str::Char iterator to check each character. - fn parse<'i, 't>( - _context: &ParserContext, - input: &mut Parser<'i, 't> - ) -> Result> { - let location = input.current_source_location(); - let path_string = input.expect_string()?.as_ref(); - if path_string.is_empty() { - // Treat an empty string as invalid, so we will not set it. - return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - - // Parse the svg path string as multiple sub-paths. - let mut path_parser = PathParser { - chars: path_string.chars().peekable(), - path: Vec::new(), - }; - while skip_wsp(&mut path_parser.chars) { - if path_parser.parse_subpath().is_err() { - return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - } - - Ok(SVGPathData::new(path_parser.path.into_boxed_slice())) - } -} - - -/// The SVG path command. -/// The fields of these commands are self-explanatory, so we skip the documents. -/// Note: the index of the control points, e.g. control1, control2, are mapping to the control -/// points of the Bézier curve in the spec. -/// -/// https://www.w3.org/TR/SVG11/paths.html#PathData -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo)] -#[allow(missing_docs)] -#[repr(C, u8)] -pub enum PathCommand { - /// The unknown type. - /// https://www.w3.org/TR/SVG/paths.html#__svg__SVGPathSeg__PATHSEG_UNKNOWN - Unknown, - /// The "moveto" command. - MoveTo { point: CoordPair, absolute: bool }, - /// The "lineto" command. - LineTo { point: CoordPair, absolute: bool }, - /// The horizontal "lineto" command. - HorizontalLineTo { x: CSSFloat, absolute: bool }, - /// The vertical "lineto" command. - VerticalLineTo { y: CSSFloat, absolute: bool }, - /// The cubic Bézier curve command. - CurveTo { control1: CoordPair, control2: CoordPair, point: CoordPair, absolute: bool }, - /// The smooth curve command. - SmoothCurveTo { control2: CoordPair, point: CoordPair, absolute: bool }, - /// The quadratic Bézier curve command. - QuadBezierCurveTo { control1: CoordPair, point: CoordPair, absolute: bool }, - /// The smooth quadratic Bézier curve command. - SmoothQuadBezierCurveTo { point: CoordPair, absolute: bool }, - /// The elliptical arc curve command. - EllipticalArc { - rx: CSSFloat, - ry: CSSFloat, - angle: CSSFloat, - large_arc_flag: bool, - sweep_flag: bool, - point: CoordPair, - absolute: bool - }, - /// The "closepath" command. - ClosePath, -} - -impl ToCss for PathCommand { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write - { - use self::PathCommand::*; - match *self { - Unknown => dest.write_str("X"), - ClosePath => dest.write_str("Z"), - MoveTo { point, absolute } => { - dest.write_char(if absolute { 'M' } else { 'm' })?; - dest.write_char(' ')?; - point.to_css(dest) - } - LineTo { point, absolute } => { - dest.write_char(if absolute { 'L' } else { 'l' })?; - dest.write_char(' ')?; - point.to_css(dest) - } - CurveTo { control1, control2, point, absolute } => { - dest.write_char(if absolute { 'C' } else { 'c' })?; - dest.write_char(' ')?; - control1.to_css(dest)?; - dest.write_char(' ')?; - control2.to_css(dest)?; - dest.write_char(' ')?; - point.to_css(dest) - }, - QuadBezierCurveTo { control1, point, absolute } => { - dest.write_char(if absolute { 'Q' } else { 'q' })?; - dest.write_char(' ')?; - control1.to_css(dest)?; - dest.write_char(' ')?; - point.to_css(dest) - }, - EllipticalArc { rx, ry, angle, large_arc_flag, sweep_flag, point, absolute } => { - dest.write_char(if absolute { 'A' } else { 'a' })?; - dest.write_char(' ')?; - rx.to_css(dest)?; - dest.write_char(' ')?; - ry.to_css(dest)?; - dest.write_char(' ')?; - angle.to_css(dest)?; - dest.write_char(' ')?; - (large_arc_flag as i32).to_css(dest)?; - dest.write_char(' ')?; - (sweep_flag as i32).to_css(dest)?; - dest.write_char(' ')?; - point.to_css(dest) - }, - HorizontalLineTo { x, absolute } => { - dest.write_char(if absolute { 'H' } else { 'h' })?; - dest.write_char(' ')?; - x.to_css(dest) - }, - VerticalLineTo { y, absolute } => { - dest.write_char(if absolute { 'V' } else { 'v' })?; - dest.write_char(' ')?; - y.to_css(dest) - }, - SmoothCurveTo { control2, point, absolute } => { - dest.write_char(if absolute { 'S' } else { 's' })?; - dest.write_char(' ')?; - control2.to_css(dest)?; - dest.write_char(' ')?; - point.to_css(dest) - }, - SmoothQuadBezierCurveTo { point, absolute } => { - dest.write_char(if absolute { 'T' } else { 't' })?; - dest.write_char(' ')?; - point.to_css(dest) - }, - } - } -} - -/// The path coord type. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] -#[repr(C)] -pub struct CoordPair(CSSFloat, CSSFloat); - -impl CoordPair { - /// Create a CoordPair. - #[inline] - pub fn new(x: CSSFloat, y: CSSFloat) -> Self { - CoordPair(x, y) - } -} - -/// Parse a pair of numbers into CoordPair. -fn parse_coord(iter: &mut Peekable) -> Result { - let x = parse_number(iter)?; - skip_comma_wsp(iter); - let y = parse_number(iter)?; - Ok(CoordPair::new(x, y)) -} - -/// This is a special version which parses the number for SVG Path. e.g. "M 0.6.5" should be parsed -/// as MoveTo with a coordinate of ("0.6", ".5"), instead of treating 0.6.5 as a non-valid floating -/// point number. In other words, the logic here is similar with that of -/// tokenizer::consume_numeric, which also consumes the number as many as possible, but here the -/// input is a Peekable and we only accept an integer of a floating point number. -/// -/// The "number" syntax in https://www.w3.org/TR/SVG/paths.html#PathDataBNF -fn parse_number(iter: &mut Peekable) -> Result { - // 1. Check optional sign. - let sign = if iter.peek().map_or(false, |&sign: &char| sign == '+' || sign == '-') { - if iter.next().unwrap() == '-' { -1. } else { 1. } - } else { - 1. - }; - - // 2. Check integer part. - let mut integral_part: f64 = 0.; - let got_dot = if !iter.peek().map_or(false, |&n: &char| n == '.') { - // If the first digit in integer part is neither a dot nor a digit, this is not a number. - if iter.peek().map_or(true, |n: &char| !n.is_ascii_digit()) { - return Err(()); - } - - while iter.peek().map_or(false, |n: &char| n.is_ascii_digit()) { - integral_part = - integral_part * 10. + iter.next().unwrap().to_digit(10).unwrap() as f64; - } - - iter.peek().map_or(false, |&n: &char| n == '.') - } else { - true - }; - - // 3. Check fractional part. - let mut fractional_part: f64 = 0.; - if got_dot { - // Consume '.'. - iter.next(); - // If the first digit in fractional part is not a digit, this is not a number. - if iter.peek().map_or(true, |n: &char| !n.is_ascii_digit()) { - return Err(()); - } - - let mut factor = 0.1; - while iter.peek().map_or(false, |n: &char| n.is_ascii_digit()) { - fractional_part += iter.next().unwrap().to_digit(10).unwrap() as f64 * factor; - factor *= 0.1; - } - } - - let mut value = sign * (integral_part + fractional_part); - - // 4. Check exp part. The segment name of SVG Path doesn't include 'E' or 'e', so it's ok to - // treat the numbers after 'E' or 'e' are in the exponential part. - if iter.peek().map_or(false, |&exp: &char| exp == 'E' || exp == 'e') { - // Consume 'E' or 'e'. - iter.next(); - let exp_sign = if iter.peek().map_or(false, |&sign: &char| sign == '+' || sign == '-') { - if iter.next().unwrap() == '-' { -1. } else { 1. } - } else { - 1. - }; - - let mut exp: f64 = 0.; - while iter.peek().map_or(false, |n: &char| n.is_ascii_digit()) { - exp = exp * 10. + iter.next().unwrap().to_digit(10).unwrap() as f64; - } - - value *= f64::powf(10., exp * exp_sign); - } - - if value.is_finite() { - Ok(value.min(::std::f32::MAX as f64).max(::std::f32::MIN as f64) as CSSFloat) - } else { - Err(()) - } -} - -/// Skip all svg whitespaces, and return true if |iter| hasn't finished. -#[inline] -fn skip_wsp(iter: &mut Peekable) -> bool { - // Note: SVG 1.1 defines the whitespaces as \u{9}, \u{20}, \u{A}, \u{D}. - // However, SVG 2 has one extra whitespace: \u{C}. - // Therefore, we follow the newest spec for the definition of whitespace, - // i.e. \u{9}, \u{20}, \u{A}, \u{C}, \u{D}, by is_ascii_whitespace(). - while iter.peek().map_or(false, |c: &char| c.is_ascii_whitespace()) { - iter.next(); - } - iter.peek().is_some() -} - -/// Skip all svg whitespaces and one comma, and return true if |iter| hasn't finished. -#[inline] -fn skip_comma_wsp(iter: &mut Peekable) -> bool { - if !skip_wsp(iter) { - return false; - } - - if *iter.peek().unwrap() != ',' { - return true; - } - iter.next(); - - skip_wsp(iter) -} diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 69a3c759927f..57b0babad628 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -165103,21 +165103,9 @@ {} ] ], - "css/motion/offset-path-string-001.html": [ + "css/motion/offset-path-string.html": [ [ - "/css/motion/offset-path-string-001.html", - [ - [ - "/css/motion/offset-path-string-ref.html", - "==" - ] - ], - {} - ] - ], - "css/motion/offset-path-string-002.html": [ - [ - "/css/motion/offset-path-string-002.html", + "/css/motion/offset-path-string.html", [ [ "/css/motion/offset-path-string-ref.html", @@ -568463,18 +568451,14 @@ "6c39e7b8f4cfafe05c07d166eb65570432912b7a", "reftest" ], - "css/motion/offset-path-string-001.html": [ - "79d957d82b8e3c603ed16598f461a805c90681dd", - "reftest" - ], - "css/motion/offset-path-string-002.html": [ - "0d2fcbbb661c2fe0e5b57ff780d78b2f8b6f627b", - "reftest" - ], "css/motion/offset-path-string-ref.html": [ "5c5ff5f6f2ddc4696f2d51266199fe052464d9e6", "support" ], + "css/motion/offset-path-string.html": [ + "79d957d82b8e3c603ed16598f461a805c90681dd", + "reftest" + ], "css/motion/offset-rotate-001.html": [ "55147698a7f2f02a57f0fe3adc8b33257d1e212f", "reftest" @@ -568516,11 +568500,11 @@ "testharness" ], "css/motion/parsing/offset-path-parsing-invalid.html": [ - "7fbd06a508a322ac0969eb11c4299de50fd254e7", + "c0a32486922b4b1b482817f409571e1e6c4219f7", "testharness" ], "css/motion/parsing/offset-path-parsing-valid.html": [ - "e7797686e4ac524ac9dc9f8525dbd5a24adeec29", + "c1e229e1a05a4c85845384ace9b884125f579415", "testharness" ], "css/motion/parsing/offset-position-parsing-invalid.html": [ diff --git a/testing/web-platform/meta/css/motion/__dir__.ini b/testing/web-platform/meta/css/motion/__dir__.ini deleted file mode 100644 index 6e20392137ad..000000000000 --- a/testing/web-platform/meta/css/motion/__dir__.ini +++ /dev/null @@ -1 +0,0 @@ -prefs: [layout.css.motion-path.enabled:true] diff --git a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-001.html.ini b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-001.html.ini index 54b010f20be5..74fd5abb8621 100644 --- a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-001.html.ini +++ b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-001.html.ini @@ -1,4 +1,7 @@ [offset-path-interpolation-001.html] + ["path('M 0 0 H 1 H 2')" and "path('M 0 0 H 3')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 0 0 H 1 H 2')" and "path('M 0 0 H 3')" at progress -1] expected: FAIL @@ -17,6 +20,9 @@ [Animation between "path('M 0 0 H 1 H 2')" and "path('M 0 0 H 3')" at progress 2] expected: FAIL + ["path('M 1 2 L 3 4 Z')" and "none" are valid offset-path values] + expected: FAIL + [Animation between "path('M 1 2 L 3 4 Z')" and "none" at progress -1] expected: FAIL @@ -26,6 +32,18 @@ [Animation between "path('M 1 2 L 3 4 Z')" and "none" at progress 0.125] expected: FAIL + [Animation between "path('M 1 2 L 3 4 Z')" and "none" at progress 0.875] + expected: FAIL + + [Animation between "path('M 1 2 L 3 4 Z')" and "none" at progress 1] + expected: FAIL + + [Animation between "path('M 1 2 L 3 4 Z')" and "none" at progress 2] + expected: FAIL + + ["path('M 10 0 H 11')" and "path('M 20 0 V 2')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 10 0 H 11')" and "path('M 20 0 V 2')" at progress -1] expected: FAIL @@ -44,6 +62,9 @@ [Animation between "path('M 10 0 H 11')" and "path('M 20 0 V 2')" at progress 2] expected: FAIL + ["path('M 1 2 L 4 6 Z')" and "path('M 1 2 H 4 V 6')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 1 2 L 4 6 Z')" and "path('M 1 2 H 4 V 6')" at progress -1] expected: FAIL @@ -62,6 +83,9 @@ [Animation between "path('M 1 2 L 4 6 Z')" and "path('M 1 2 H 4 V 6')" at progress 2] expected: FAIL + ["path('M 0 0 Z')" and "path('M 0 0 Z')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 0 0 Z')" and "path('M 0 0 Z')" at progress -1] expected: FAIL @@ -80,6 +104,9 @@ [Animation between "path('M 0 0 Z')" and "path('M 0 0 Z')" at progress 2] expected: FAIL + ["path('M 20 70')" and "path('M 100 30')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 20 70')" and "path('M 100 30')" at progress -1] expected: FAIL @@ -98,6 +125,9 @@ [Animation between "path('M 20 70')" and "path('M 100 30')" at progress 2] expected: FAIL + ["path('m 20 70')" and "path('m 100 30')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 20 70')" and "path('m 100 30')" at progress -1] expected: FAIL @@ -116,6 +146,9 @@ [Animation between "path('m 20 70')" and "path('m 100 30')" at progress 2] expected: FAIL + ["path('m 100 200 L 120 270')" and "path('m 100 200 L 200 230')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 100 200 L 120 270')" and "path('m 100 200 L 200 230')" at progress -1] expected: FAIL @@ -134,6 +167,9 @@ [Animation between "path('m 100 200 L 120 270')" and "path('m 100 200 L 200 230')" at progress 2] expected: FAIL + ["path('m 100 200 l 20 70')" and "path('m 100 200 l 100 30')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 100 200 l 20 70')" and "path('m 100 200 l 100 30')" at progress -1] expected: FAIL diff --git a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-002.html.ini b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-002.html.ini index 0da0fa965620..6cc072ce9819 100644 --- a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-002.html.ini +++ b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-002.html.ini @@ -1,4 +1,7 @@ [offset-path-interpolation-002.html] + ["path('M 20 10 C 32 42 52 62 120 2200')" and "path('M 20 10 C 40 50 60 70 200 3000')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 20 10 C 32 42 52 62 120 2200')" and "path('M 20 10 C 40 50 60 70 200 3000')" at progress -1] expected: FAIL @@ -17,6 +20,9 @@ [Animation between "path('M 20 10 C 32 42 52 62 120 2200')" and "path('M 20 10 C 40 50 60 70 200 3000')" at progress 2] expected: FAIL + ["path('m 20 10 c 12 32 32 52 100 2190')" and "path('m 20 10 c 20 40 40 60 180 2990')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 20 10 c 12 32 32 52 100 2190')" and "path('m 20 10 c 20 40 40 60 180 2990')" at progress -1] expected: FAIL @@ -35,6 +41,9 @@ [Animation between "path('m 20 10 c 12 32 32 52 100 2190')" and "path('m 20 10 c 20 40 40 60 180 2990')" at progress 2] expected: FAIL + ["path('M 20 10 Q 32 42 120 2200')" and "path('M 20 10 Q 40 50 200 3000')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 20 10 Q 32 42 120 2200')" and "path('M 20 10 Q 40 50 200 3000')" at progress -1] expected: FAIL @@ -53,6 +62,9 @@ [Animation between "path('M 20 10 Q 32 42 120 2200')" and "path('M 20 10 Q 40 50 200 3000')" at progress 2] expected: FAIL + ["path('m 20 10 q 12 32 100 2190')" and "path('m 20 10 q 20 40 180 2990')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 20 10 q 12 32 100 2190')" and "path('m 20 10 q 20 40 180 2990')" at progress -1] expected: FAIL @@ -71,6 +83,9 @@ [Animation between "path('m 20 10 q 12 32 100 2190')" and "path('m 20 10 q 20 40 180 2990')" at progress 2] expected: FAIL + ["path('M 100 400 A 10 20 30 1 0 140 450')" and "path('M 300 200 A 50 60 70 0 1 380 290')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 100 400 A 10 20 30 1 0 140 450')" and "path('M 300 200 A 50 60 70 0 1 380 290')" at progress -1] expected: FAIL @@ -89,6 +104,9 @@ [Animation between "path('M 100 400 A 10 20 30 1 0 140 450')" and "path('M 300 200 A 50 60 70 0 1 380 290')" at progress 2] expected: FAIL + ["path('m 100 400 a 10 20 30 1 0 40 50')" and "path('m 300 200 a 50 60 70 0 1 80 90')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 100 400 a 10 20 30 1 0 40 50')" and "path('m 300 200 a 50 60 70 0 1 80 90')" at progress -1] expected: FAIL diff --git a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-003.html.ini b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-003.html.ini index 8f754cdc1d55..b4677ff62c5e 100644 --- a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-003.html.ini +++ b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-003.html.ini @@ -1,4 +1,7 @@ [offset-path-interpolation-003.html] + ["path('M 50 60 H 70')" and "path('M 10 140 H 270')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 50 60 H 70')" and "path('M 10 140 H 270')" at progress -1] expected: FAIL @@ -17,6 +20,9 @@ [Animation between "path('M 50 60 H 70')" and "path('M 10 140 H 270')" at progress 2] expected: FAIL + ["path('m 50 60 h 20')" and "path('m 10 140 h 260')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 50 60 h 20')" and "path('m 10 140 h 260')" at progress -1] expected: FAIL @@ -35,6 +41,9 @@ [Animation between "path('m 50 60 h 20')" and "path('m 10 140 h 260')" at progress 2] expected: FAIL + ["path('M 50 60 V 70')" and "path('M 10 140 V 270')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 50 60 V 70')" and "path('M 10 140 V 270')" at progress -1] expected: FAIL @@ -53,6 +62,9 @@ [Animation between "path('M 50 60 V 70')" and "path('M 10 140 V 270')" at progress 2] expected: FAIL + ["path('m 50 60 v 10')" and "path('m 10 140 v 130')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 50 60 v 10')" and "path('m 10 140 v 130')" at progress -1] expected: FAIL @@ -71,6 +83,9 @@ [Animation between "path('m 50 60 v 10')" and "path('m 10 140 v 130')" at progress 2] expected: FAIL + ["path('M 12 34 S 45 67 89 123')" and "path('M 20 26 S 61 51 113 99')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 12 34 S 45 67 89 123')" and "path('M 20 26 S 61 51 113 99')" at progress -1] expected: FAIL @@ -89,6 +104,9 @@ [Animation between "path('M 12 34 S 45 67 89 123')" and "path('M 20 26 S 61 51 113 99')" at progress 2] expected: FAIL + ["path('m 12 34 s 33 33 77 89')" and "path('m 20 26 s 41 25 93 73')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 12 34 s 33 33 77 89')" and "path('m 20 26 s 41 25 93 73')" at progress -1] expected: FAIL @@ -107,6 +125,9 @@ [Animation between "path('m 12 34 s 33 33 77 89')" and "path('m 20 26 s 41 25 93 73')" at progress 2] expected: FAIL + ["path('M 12 34 T 45 67')" and "path('M 20 26 T 61 51')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 12 34 T 45 67')" and "path('M 20 26 T 61 51')" at progress -1] expected: FAIL @@ -125,6 +146,9 @@ [Animation between "path('M 12 34 T 45 67')" and "path('M 20 26 T 61 51')" at progress 2] expected: FAIL + ["path('m 12 34 t 33 33')" and "path('m 20 26 t 41 25')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 12 34 t 33 33')" and "path('m 20 26 t 41 25')" at progress -1] expected: FAIL diff --git a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-004.html.ini b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-004.html.ini index 6d85a6a7e42c..9540cff46808 100644 --- a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-004.html.ini +++ b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-004.html.ini @@ -1,4 +1,7 @@ [offset-path-interpolation-004.html] + ["path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z')" at progress -1] expected: FAIL @@ -17,6 +20,9 @@ [Animation between "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 300 100 z')" at progress 2] expected: FAIL + ["path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')" are valid offset-path values] + expected: FAIL + [Animation between "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')" at progress -1] expected: FAIL @@ -35,6 +41,9 @@ [Animation between "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 200 100 Z')" and "path('M 0 0 L 100 100 m 0 100 l 100 0 z l 100 -100 z')" at progress 2] expected: FAIL + ["path('m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130')" and "path('M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130')" and "path('M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220')" at progress -1] expected: FAIL @@ -53,6 +62,9 @@ [Animation between "path('m 10 20 l 40 50 z l 40 60 z m 60 70 l 90 60 z t 70 130')" and "path('M 210 220 L 170 190 Z L 90 120 Z M 110 130 L 200 230 Z T 220 220')" at progress 2] expected: FAIL + ["path('m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160')" and "path('M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160')" and "path('M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330')" at progress -1] expected: FAIL @@ -71,6 +83,9 @@ [Animation between "path('m 10 20 c 40 50 30 60 80 70 c 120 130 170 140 110 160')" and "path('M 130 100 C 130 150 120 160 210 170 C 290 300 340 310 320 330')" at progress 2] expected: FAIL + ["path('m 10 20 q 30 60 40 50 q 110 80 90 80')" and "path('M 130 100 Q 120 160 130 150 Q 200 150 180 190')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 q 30 60 40 50 q 110 80 90 80')" and "path('M 130 100 Q 120 160 130 150 Q 200 150 180 190')" at progress -1] expected: FAIL @@ -89,6 +104,9 @@ [Animation between "path('m 10 20 q 30 60 40 50 q 110 80 90 80')" and "path('M 130 100 Q 120 160 130 150 Q 200 150 180 190')" at progress 2] expected: FAIL + ["path('m 10 20 s 30 60 40 50 s 110 60 90 70')" and "path('M 130 140 S 120 160 130 150 S 200 170 140 180')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 s 30 60 40 50 s 110 60 90 70')" and "path('M 130 140 S 120 160 130 150 S 200 170 140 180')" at progress -1] expected: FAIL @@ -107,6 +125,9 @@ [Animation between "path('m 10 20 s 30 60 40 50 s 110 60 90 70')" and "path('M 130 140 S 120 160 130 150 S 200 170 140 180')" at progress 2] expected: FAIL + ["path('m 10 20 h 30 v 60 h 10 v -10 l 110 60')" and "path('M 130 140 H 120 V 160 H 130 V 150 L 200 170')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 h 30 v 60 h 10 v -10 l 110 60')" and "path('M 130 140 H 120 V 160 H 130 V 150 L 200 170')" at progress -1] expected: FAIL @@ -125,6 +146,9 @@ [Animation between "path('m 10 20 h 30 v 60 h 10 v -10 l 110 60')" and "path('M 130 140 H 120 V 160 H 130 V 150 L 200 170')" at progress 2] expected: FAIL + ["path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')" and "path('M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80')" are valid offset-path values] + expected: FAIL + [Animation between "path('m 10 20 a 10 20 30 1 0 40 50 a 110 120 30 1 1 140 50')" and "path('M 18 12 A 50 100 70 0 1 90 110 A 150 160 70 0 1 70 80')" at progress -1] expected: FAIL diff --git a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-005.html.ini b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-005.html.ini index 42ed84a3bb0e..189aa04a4d8a 100644 --- a/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-005.html.ini +++ b/testing/web-platform/meta/css/motion/animation/offset-path-interpolation-005.html.ini @@ -32,9 +32,27 @@ [Animation between "ray(0deg closest-corner)" and "none" at progress 0.125] expected: FAIL + [Animation between "ray(0deg closest-corner)" and "none" at progress 0.875] + expected: FAIL + + [Animation between "ray(0deg closest-corner)" and "none" at progress 1] + expected: FAIL + + [Animation between "ray(0deg closest-corner)" and "none" at progress 2] + expected: FAIL + ["none" and "ray(20deg closest-side)" are valid offset-path values] expected: FAIL + [Animation between "none" and "ray(20deg closest-side)" at progress -1] + expected: FAIL + + [Animation between "none" and "ray(20deg closest-side)" at progress 0] + expected: FAIL + + [Animation between "none" and "ray(20deg closest-side)" at progress 0.125] + expected: FAIL + [Animation between "none" and "ray(20deg closest-side)" at progress 0.875] expected: FAIL diff --git a/testing/web-platform/meta/css/motion/offset-path-string-001.html.ini b/testing/web-platform/meta/css/motion/offset-path-string-001.html.ini deleted file mode 100644 index 5931951b8baf..000000000000 --- a/testing/web-platform/meta/css/motion/offset-path-string-001.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[offset-path-string-001.html] - expected: FAIL - bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1429299 diff --git a/testing/web-platform/meta/css/motion/offset-path-string.html.ini b/testing/web-platform/meta/css/motion/offset-path-string.html.ini new file mode 100644 index 000000000000..e91dc7c30033 --- /dev/null +++ b/testing/web-platform/meta/css/motion/offset-path-string.html.ini @@ -0,0 +1,2 @@ +[offset-path-string.html] + expected: FAIL diff --git a/testing/web-platform/meta/css/motion/parsing/offset-path-parsing-valid.html.ini b/testing/web-platform/meta/css/motion/parsing/offset-path-parsing-valid.html.ini index 770115aa1d6f..ba450f8f0005 100644 --- a/testing/web-platform/meta/css/motion/parsing/offset-path-parsing-valid.html.ini +++ b/testing/web-platform/meta/css/motion/parsing/offset-path-parsing-valid.html.ini @@ -5,6 +5,12 @@ [Serialization should round-trip after setting e.style['offset-path'\] = "fill-box ellipse(50% 60%)"] expected: FAIL + [e.style['offset-path'\] = "none" should set the property value] + expected: FAIL + + [Serialization should round-trip after setting e.style['offset-path'\] = "none"] + expected: FAIL + [e.style['offset-path'\] = "ray(0rad closest-side)" should set the property value] expected: FAIL @@ -38,6 +44,18 @@ [e.style['offset-path'\] = "ray(calc(180deg - 45deg) farthest-side)" should set the property value] expected: FAIL + [e.style['offset-path'\] = "path('m 0 0 h -100')" should set the property value] + expected: FAIL + + [Serialization should round-trip after setting e.style['offset-path'\] = "path('m 0 0 h -100')"] + expected: FAIL + + [e.style['offset-path'\] = "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z')" should set the property value] + expected: FAIL + + [Serialization should round-trip after setting e.style['offset-path'\] = "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z')"] + expected: FAIL + [e.style['offset-path'\] = "url(\\"http://www.example.com/index.html#polyline1\\")" should set the property value] expected: FAIL diff --git a/testing/web-platform/tests/css/motion/offset-path-string-002.html b/testing/web-platform/tests/css/motion/offset-path-string-002.html deleted file mode 100644 index 0d2fcbbb661c..000000000000 --- a/testing/web-platform/tests/css/motion/offset-path-string-002.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - CSS Motion Path: path(string) paths - - - - - - -
- - diff --git a/testing/web-platform/tests/css/motion/offset-path-string-001.html b/testing/web-platform/tests/css/motion/offset-path-string.html similarity index 100% rename from testing/web-platform/tests/css/motion/offset-path-string-001.html rename to testing/web-platform/tests/css/motion/offset-path-string.html diff --git a/testing/web-platform/tests/css/motion/parsing/offset-path-parsing-invalid.html b/testing/web-platform/tests/css/motion/parsing/offset-path-parsing-invalid.html index 7fbd06a508a3..c0a32486922b 100644 --- a/testing/web-platform/tests/css/motion/parsing/offset-path-parsing-invalid.html +++ b/testing/web-platform/tests/css/motion/parsing/offset-path-parsing-invalid.html @@ -14,7 +14,7 @@