Bug 1884425 - Introduce PathOrShapeFunciton for path() and shape(). r=firefox-style-system-reviewers,zrhoffman

Use this as a wrapper for `path()` and `shape()`, so it'd be easier to
specialize its `Animate` trait.

Differential Revision: https://phabricator.services.mozilla.com/D205490
This commit is contained in:
Boris Chiou 2024-03-28 19:42:13 +00:00
Родитель 258c21d8ec
Коммит 4385764edf
6 изменённых файлов: 60 добавлений и 21 удалений

Просмотреть файл

@ -740,18 +740,22 @@ already_AddRefed<gfx::Path> MotionPathUtils::BuildPath(
case StyleBasicShape::Tag::Polygon:
return ShapeUtils::BuildPolygonPath(aBasicShape, aCoordBox,
AppUnitsPerCSSPixel(), aPathBuilder);
case StyleBasicShape::Tag::Path:
case StyleBasicShape::Tag::PathOrShape: {
// FIXME: Bug 1836847. Once we support "at <position>" for path(), we have
// to also check its containing block as well. For now, we are still
// building its gfx::Path directly by its SVGPathData without other
// reference. https://github.com/w3c/fxtf-drafts/issues/504
return BuildSVGPath(aBasicShape.AsPath().path, aPathBuilder);
case StyleBasicShape::Tag::Shape:
const auto& pathOrShape = aBasicShape.AsPathOrShape();
if (pathOrShape.IsPath()) {
return BuildSVGPath(pathOrShape.AsPath().path, aPathBuilder);
}
// Note that shape() always defines the initial position, i.e. "from x y",
// by its first move command, so |aOffsetPosition|, i.e. offset-position
// property, is ignored.
return BuildShape(aBasicShape.AsShape().commands.AsSpan(), aPathBuilder,
return BuildShape(pathOrShape.AsShape().commands.AsSpan(), aPathBuilder,
aCoordBox);
}
}
return nullptr;

Просмотреть файл

@ -2507,8 +2507,7 @@ nsFloatManager::ShapeInfo::CreateBasicShape(const StyleBasicShape& aBasicShape,
case StyleBasicShape::Tag::Rect:
return CreateInset(aBasicShape, aShapeMargin, aFrame, aShapeBoxRect, aWM,
aContainerSize);
case StyleBasicShape::Tag::Path:
case StyleBasicShape::Tag::Shape:
case StyleBasicShape::Tag::PathOrShape:
MOZ_ASSERT_UNREACHABLE("Unsupported basic shape");
}
return nullptr;

Просмотреть файл

@ -121,10 +121,10 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPath(
return CreateClipPathPolygon(aDrawTarget, r);
case StyleBasicShape::Tag::Rect:
return CreateClipPathInset(aDrawTarget, r);
case StyleBasicShape::Tag::Path:
return CreateClipPathPath(aDrawTarget, r);
case StyleBasicShape::Tag::Shape:
return CreateClipPathShape(aDrawTarget, r);
case StyleBasicShape::Tag::PathOrShape:
return basicShape.AsPathOrShape().IsPath()
? CreateClipPathPath(aDrawTarget, r)
: CreateClipPathShape(aDrawTarget, r);
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type");
}
@ -177,7 +177,7 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPathInset(
already_AddRefed<Path> CSSClipPathInstance::CreateClipPathPath(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& path = mClipPathStyle.AsShape()._0->AsPath();
const auto& path = mClipPathStyle.AsShape()._0->AsPathOrShape().AsPath();
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
path.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
@ -196,7 +196,7 @@ already_AddRefed<Path> CSSClipPathInstance::CreateClipPathPath(
already_AddRefed<Path> CSSClipPathInstance::CreateClipPathShape(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& shape = mClipPathStyle.AsShape()._0->AsShape();
const auto& shape = mClipPathStyle.AsShape()._0->AsPathOrShape().AsShape();
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
shape.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING

Просмотреть файл

@ -204,10 +204,8 @@ pub enum GenericBasicShape<
),
/// Defines a polygon with pair arguments.
Polygon(GenericPolygon<LengthPercentage>),
/// Defines a path with SVG path syntax.
Path(Path),
/// Defines a shape function, which is identical to path(() but it uses the CSS syntax.
Shape(#[css(field_bound)] Shape<Angle, LengthPercentage>),
/// Defines a path() or shape().
PathOrShape(#[css(field_bound)] GenericPathOrShapeFunction<Angle, LengthPercentage>),
}
pub use self::GenericBasicShape as BasicShape;
@ -371,6 +369,31 @@ pub use self::GenericPolygon as Polygon;
#[repr(C)]
pub struct PolygonCoord<LengthPercentage>(pub LengthPercentage, pub LengthPercentage);
/// path() function or shape() function.
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToAnimatedValue,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
pub enum GenericPathOrShapeFunction<Angle, LengthPercentage> {
/// Defines a path with SVG path syntax.
Path(Path),
/// Defines a shape function, which is identical to path() but it uses the CSS syntax.
Shape(#[css(field_bound)] Shape<Angle, LengthPercentage>),
}
// https://drafts.csswg.org/css-shapes/#typedef-fill-rule
// NOTE: Basic shapes spec says that these are the only two values, however
// https://www.w3.org/TR/SVG/painting.html#FillRuleProperty

Просмотреть файл

@ -63,6 +63,9 @@ pub type ShapeRadius = generic::ShapeRadius<NonNegativeLengthPercentage>;
/// The specified value of `Polygon`.
pub type Polygon = generic::GenericPolygon<LengthPercentage>;
/// The specified value of `PathOrShapeFunction`.
pub type PathOrShapeFunction = generic::GenericPathOrShapeFunction<Angle, LengthPercentage>;
/// The specified value of `ShapeCommand`.
pub type ShapeCommand = generic::GenericShapeCommand<Angle, LengthPercentage>;
@ -335,14 +338,17 @@ impl BasicShape {
.map(BasicShape::Polygon)
},
"path" if flags.contains(AllowedBasicShapes::PATH) => {
Path::parse_function_arguments(i, shape_type).map(BasicShape::Path)
Path::parse_function_arguments(i, shape_type)
.map(PathOrShapeFunction::Path)
.map(BasicShape::PathOrShape)
},
"shape"
if flags.contains(AllowedBasicShapes::SHAPE)
&& static_prefs::pref!("layout.css.basic-shape-shape.enabled") =>
{
generic::Shape::parse_function_arguments(context, i, shape_type)
.map(BasicShape::Shape)
.map(PathOrShapeFunction::Shape)
.map(BasicShape::PathOrShape)
},
_ => Err(location
.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))),

Просмотреть файл

@ -1038,12 +1038,19 @@ renaming_overrides_prefixing = true
// Return true if the <basic-shape> is path().
bool IsPath() const {
return IsOffsetPath() && AsOffsetPath().path->IsShape() &&
AsOffsetPath().path->AsShape().IsPath();
if (!IsOffsetPath()) {
return false;
}
const auto& path = AsOffsetPath().path;
if (!path->IsShape()) {
return false;
}
const auto& shape = path->AsShape();
return shape.IsPathOrShape() && shape.AsPathOrShape().IsPath();
}
const StyleSVGPathData& AsSVGPathData() const {
return AsOffsetPath().path->AsShape().AsPath().path;
return AsOffsetPath().path->AsShape().AsPathOrShape().AsPath().path;
}
// Return true if this is "<basic-shape> || <coord-box>".