Bug 1548691 - Use the owned slice type for basic shape polygon coordinates. r=TYLin,heycam

This enables destructors for tagged unions in cbindgen, implemented in:

 * https://github.com/eqrion/cbindgen/pull/333

Which allow us to properly generate a destructor for the cbindgen-generated
StyleBasicShape (which now contains an OwnedSlice).

For now, we still use the glue code to go from Box<BasicShape> to
UniquePtr<BasicShape>. But that will change in the future when we generate even
more stuff and remove all the glue.

I could add support for copy-constructor generation to cbindgen for tagged
enums, but I'm not sure if it'll end up being needed, and copy-constructing
unions in C++ is always very tricky.

Differential Revision: https://phabricator.services.mozilla.com/D29769

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-05-09 11:24:57 +00:00
Родитель 7d9dca2244
Коммит 38065025d9
39 изменённых файлов: 215 добавлений и 831 удалений

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

@ -16,89 +16,79 @@
namespace mozilla {
nscoord ShapeUtils::ComputeShapeRadius(const StyleShapeRadius aType,
nscoord ShapeUtils::ComputeShapeRadius(const StyleShapeRadius& aType,
const nscoord aCenter,
const nscoord aPosMin,
const nscoord aPosMax) {
MOZ_ASSERT(aType.IsFarthestSide() || aType.IsClosestSide());
nscoord dist1 = std::abs(aPosMin - aCenter);
nscoord dist2 = std::abs(aPosMax - aCenter);
nscoord length = 0;
switch (aType) {
case StyleShapeRadius::FarthestSide:
length = dist1 > dist2 ? dist1 : dist2;
break;
case StyleShapeRadius::ClosestSide:
length = dist1 > dist2 ? dist2 : dist1;
break;
if (aType.IsFarthestSide()) {
length = dist1 > dist2 ? dist1 : dist2;
} else {
length = dist1 > dist2 ? dist2 : dist1;
}
return length;
}
nsPoint ShapeUtils::ComputeCircleOrEllipseCenter(
const StyleBasicShape& aBasicShape, const nsRect& aRefBox) {
MOZ_ASSERT(aBasicShape.GetShapeType() == StyleBasicShapeType::Circle ||
aBasicShape.GetShapeType() == StyleBasicShapeType::Ellipse,
MOZ_ASSERT(aBasicShape.IsCircle() || aBasicShape.IsEllipse(),
"The basic shape must be circle() or ellipse!");
const auto& position = aBasicShape.IsCircle()
? aBasicShape.AsCircle().position
: aBasicShape.AsEllipse().position;
nsPoint topLeft, anchor;
nsSize size(aRefBox.Size());
nsImageRenderer::ComputeObjectAnchorPoint(aBasicShape.GetPosition(), size,
size, &topLeft, &anchor);
nsImageRenderer::ComputeObjectAnchorPoint(position, size, size, &topLeft,
&anchor);
return anchor + aRefBox.TopLeft();
}
nscoord ShapeUtils::ComputeCircleRadius(const StyleBasicShape& aBasicShape,
const nsPoint& aCenter,
const nsRect& aRefBox) {
MOZ_ASSERT(aBasicShape.GetShapeType() == StyleBasicShapeType::Circle,
"The basic shape must be circle()!");
const nsTArray<nsStyleCoord>& coords = aBasicShape.Coordinates();
MOZ_ASSERT(coords.Length() == 1, "wrong number of arguments");
nscoord r = 0;
if (coords[0].GetUnit() == eStyleUnit_Enumerated) {
const auto styleShapeRadius = coords[0].GetEnumValue<StyleShapeRadius>();
nscoord horizontal = ComputeShapeRadius(styleShapeRadius, aCenter.x,
aRefBox.x, aRefBox.XMost());
nscoord vertical = ComputeShapeRadius(styleShapeRadius, aCenter.y,
aRefBox.y, aRefBox.YMost());
r = styleShapeRadius == StyleShapeRadius::FarthestSide
? std::max(horizontal, vertical)
: std::min(horizontal, vertical);
} else {
// We resolve percent <shape-radius> value for circle() as defined here:
// https://drafts.csswg.org/css-shapes/#funcdef-circle
double referenceLength = SVGContentUtils::ComputeNormalizedHypotenuse(
aRefBox.width, aRefBox.height);
r = coords[0].ComputeCoordPercentCalc(NSToCoordRound(referenceLength));
MOZ_ASSERT(aBasicShape.IsCircle(), "The basic shape must be circle()!");
const auto& radius = aBasicShape.AsCircle().radius;
if (radius.IsLength()) {
return radius.AsLength().Resolve([&] {
// We resolve percent <shape-radius> value for circle() as defined here:
// https://drafts.csswg.org/css-shapes/#funcdef-circle
double referenceLength = SVGContentUtils::ComputeNormalizedHypotenuse(
aRefBox.width, aRefBox.height);
return NSToCoordRound(referenceLength);
});
}
return r;
nscoord horizontal =
ComputeShapeRadius(radius, aCenter.x, aRefBox.x, aRefBox.XMost());
nscoord vertical =
ComputeShapeRadius(radius, aCenter.y, aRefBox.y, aRefBox.YMost());
return radius.IsFarthestSide() ? std::max(horizontal, vertical)
: std::min(horizontal, vertical);
}
nsSize ShapeUtils::ComputeEllipseRadii(const StyleBasicShape& aBasicShape,
const nsPoint& aCenter,
const nsRect& aRefBox) {
MOZ_ASSERT(aBasicShape.GetShapeType() == StyleBasicShapeType::Ellipse,
"The basic shape must be ellipse()!");
const nsTArray<nsStyleCoord>& coords = aBasicShape.Coordinates();
MOZ_ASSERT(coords.Length() == 2, "wrong number of arguments");
MOZ_ASSERT(aBasicShape.IsEllipse(), "The basic shape must be ellipse()!");
const auto& ellipse = aBasicShape.AsEllipse();
nsSize radii;
if (coords[0].GetUnit() == eStyleUnit_Enumerated) {
const StyleShapeRadius radiusX = coords[0].GetEnumValue<StyleShapeRadius>();
radii.width =
ComputeShapeRadius(radiusX, aCenter.x, aRefBox.x, aRefBox.XMost());
if (ellipse.semiaxis_x.IsLength()) {
radii.width = ellipse.semiaxis_x.AsLength().Resolve(aRefBox.width);
} else {
radii.width = coords[0].ComputeCoordPercentCalc(aRefBox.width);
radii.width = ComputeShapeRadius(ellipse.semiaxis_x, aCenter.x, aRefBox.x,
aRefBox.XMost());
}
if (coords[1].GetUnit() == eStyleUnit_Enumerated) {
const StyleShapeRadius radiusY = coords[1].GetEnumValue<StyleShapeRadius>();
radii.height =
ComputeShapeRadius(radiusY, aCenter.y, aRefBox.y, aRefBox.YMost());
if (ellipse.semiaxis_y.IsLength()) {
radii.height = ellipse.semiaxis_y.AsLength().Resolve(aRefBox.height);
} else {
radii.height = coords[1].ComputeCoordPercentCalc(aRefBox.height);
radii.height = ComputeShapeRadius(ellipse.semiaxis_y, aCenter.y, aRefBox.y,
aRefBox.YMost());
}
return radii;
@ -107,16 +97,11 @@ nsSize ShapeUtils::ComputeEllipseRadii(const StyleBasicShape& aBasicShape,
/* static */
nsRect ShapeUtils::ComputeInsetRect(const StyleBasicShape& aBasicShape,
const nsRect& aRefBox) {
MOZ_ASSERT(aBasicShape.GetShapeType() == StyleBasicShapeType::Inset,
"The basic shape must be inset()!");
const nsTArray<nsStyleCoord>& coords = aBasicShape.Coordinates();
MOZ_ASSERT(coords.Length() == 4, "wrong number of arguments");
nsMargin inset(coords[0].ComputeCoordPercentCalc(aRefBox.Height()),
coords[1].ComputeCoordPercentCalc(aRefBox.Width()),
coords[2].ComputeCoordPercentCalc(aRefBox.Height()),
coords[3].ComputeCoordPercentCalc(aRefBox.Width()));
MOZ_ASSERT(aBasicShape.IsInset(), "The basic shape must be inset()!");
const auto& rect = aBasicShape.AsInset().rect;
nsMargin inset(
rect._0.Resolve(aRefBox.Height()), rect._1.Resolve(aRefBox.Width()),
rect._2.Resolve(aRefBox.Height()), rect._3.Resolve(aRefBox.Width()));
nscoord x = aRefBox.X() + inset.left;
nscoord width = aRefBox.Width() - inset.LeftRight();
@ -142,7 +127,7 @@ nsRect ShapeUtils::ComputeInsetRect(const StyleBasicShape& aBasicShape,
bool ShapeUtils::ComputeInsetRadii(const StyleBasicShape& aBasicShape,
const nsRect& aInsetRect,
const nsRect& aRefBox, nscoord aRadii[8]) {
const auto& radius = aBasicShape.GetRadius();
const auto& radius = aBasicShape.AsInset().round;
return nsIFrame::ComputeBorderRadii(radius, aInsetRect.Size(), aRefBox.Size(),
Sides(), aRadii);
}
@ -150,19 +135,14 @@ bool ShapeUtils::ComputeInsetRadii(const StyleBasicShape& aBasicShape,
/* static */
nsTArray<nsPoint> ShapeUtils::ComputePolygonVertices(
const StyleBasicShape& aBasicShape, const nsRect& aRefBox) {
MOZ_ASSERT(aBasicShape.GetShapeType() == StyleBasicShapeType::Polygon,
"The basic shape must be polygon()!");
MOZ_ASSERT(aBasicShape.IsPolygon(), "The basic shape must be polygon()!");
const nsTArray<nsStyleCoord>& coords = aBasicShape.Coordinates();
MOZ_ASSERT(coords.Length() % 2 == 0 && coords.Length() >= 2,
"Wrong number of arguments!");
nsTArray<nsPoint> vertices(coords.Length() / 2);
for (size_t i = 0; i + 1 < coords.Length(); i += 2) {
vertices.AppendElement(
nsPoint(coords[i].ComputeCoordPercentCalc(aRefBox.width),
coords[i + 1].ComputeCoordPercentCalc(aRefBox.height)) +
aRefBox.TopLeft());
auto coords = aBasicShape.AsPolygon().coordinates.AsSpan();
nsTArray<nsPoint> vertices(coords.Length());
for (const StylePolygonCoord<LengthPercentage>& point : coords) {
vertices.AppendElement(nsPoint(point._0.Resolve(aRefBox.width),
point._1.Resolve(aRefBox.height)) +
aRefBox.TopLeft());
}
return vertices;
}

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

@ -10,14 +10,13 @@
#include "nsCoord.h"
#include "nsSize.h"
#include "nsStyleConsts.h"
#include "nsStyleCoord.h"
#include "nsTArray.h"
struct nsPoint;
struct nsRect;
namespace mozilla {
class StyleBasicShape;
// ShapeUtils is a namespace class containing utility functions related to
// processing basic shapes in the CSS Shapes Module.
// https://drafts.csswg.org/css-shapes/#basic-shape-functions
@ -28,7 +27,7 @@ struct ShapeUtils final {
// caller needs to call for both dimensions and combine the result.
// https://drafts.csswg.org/css-shapes/#typedef-shape-radius.
// @return The length of the radius in app units.
static nscoord ComputeShapeRadius(const StyleShapeRadius aType,
static nscoord ComputeShapeRadius(const StyleShapeRadius& aType,
const nscoord aCenter,
const nscoord aPosMin,
const nscoord aPosMax);

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

@ -2503,15 +2503,15 @@ nsFloatManager::ShapeInfo::CreateBasicShape(const StyleBasicShape& aBasicShape,
const LogicalRect& aMarginRect,
WritingMode aWM,
const nsSize& aContainerSize) {
switch (aBasicShape.GetShapeType()) {
case StyleBasicShapeType::Polygon:
switch (aBasicShape.tag) {
case StyleBasicShape::Tag::Polygon:
return CreatePolygon(aBasicShape, aShapeMargin, aFrame, aShapeBoxRect,
aMarginRect, aWM, aContainerSize);
case StyleBasicShapeType::Circle:
case StyleBasicShapeType::Ellipse:
case StyleBasicShape::Tag::Circle:
case StyleBasicShape::Tag::Ellipse:
return CreateCircleOrEllipse(aBasicShape, aShapeMargin, aFrame,
aShapeBoxRect, aWM, aContainerSize);
case StyleBasicShapeType::Inset:
case StyleBasicShape::Tag::Inset:
return CreateInset(aBasicShape, aShapeMargin, aFrame, aShapeBoxRect, aWM,
aContainerSize);
}
@ -2599,8 +2599,7 @@ nsFloatManager::ShapeInfo::CreateCircleOrEllipse(
// Compute the circle or ellipse radii.
nsSize radii;
StyleBasicShapeType type = aBasicShape.GetShapeType();
if (type == StyleBasicShapeType::Circle) {
if (aBasicShape.IsCircle()) {
nscoord radius = ShapeUtils::ComputeCircleRadius(
aBasicShape, physicalCenter, physicalShapeBoxRect);
// Circles can use the three argument, math constructor for
@ -2609,7 +2608,7 @@ nsFloatManager::ShapeInfo::CreateCircleOrEllipse(
return MakeUnique<EllipseShapeInfo>(logicalCenter, radii, aShapeMargin);
}
MOZ_ASSERT(type == StyleBasicShapeType::Ellipse);
MOZ_ASSERT(aBasicShape.IsEllipse());
nsSize physicalRadii = ShapeUtils::ComputeEllipseRadii(
aBasicShape, physicalCenter, physicalShapeBoxRect);
LogicalSize logicalRadii(aWM, physicalRadii);

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

@ -24,7 +24,6 @@ class nsPresContext;
namespace mozilla {
struct ReflowInput;
class PresShell;
class StyleBasicShape;
} // namespace mozilla
enum class nsFlowAreaRectFlags : uint32_t {

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

@ -9594,8 +9594,8 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
AutoTArray<wr::ComplexClipRegion, 1> clipRegions;
wr::LayoutRect rect;
switch (shape.GetShapeType()) {
case StyleBasicShapeType::Inset: {
switch (shape.tag) {
case StyleBasicShape::Tag::Inset: {
const nsRect insetRect = ShapeUtils::ComputeInsetRect(shape, refBox) +
aDisplayItem.ToReferenceFrame();
@ -9610,12 +9610,12 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
LayoutDeviceRect::FromAppUnits(insetRect, appUnitsPerDevPixel));
break;
}
case StyleBasicShapeType::Ellipse:
case StyleBasicShapeType::Circle: {
case StyleBasicShape::Tag::Ellipse:
case StyleBasicShape::Tag::Circle: {
nsPoint center = ShapeUtils::ComputeCircleOrEllipseCenter(shape, refBox);
nsSize radii;
if (shape.GetShapeType() == StyleBasicShapeType::Ellipse) {
if (shape.IsEllipse()) {
radii = ShapeUtils::ComputeEllipseRadii(shape, center, refBox);
} else {
nscoord radius = ShapeUtils::ComputeCircleRadius(shape, center, refBox);

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

@ -1560,11 +1560,6 @@ void Gecko_StyleShapeSource_SetURLValue(StyleShapeSource* aShape,
aShape->SetURL(*aURL);
}
void Gecko_NewBasicShape(StyleShapeSource* aShape, StyleBasicShapeType aType) {
aShape->SetBasicShape(MakeUnique<StyleBasicShape>(aType),
StyleGeometryBox::NoBox);
}
void Gecko_NewShapeImage(StyleShapeSource* aShape) {
aShape->SetShapeImage(MakeUnique<nsStyleImage>());
}

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

@ -527,9 +527,6 @@ void Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* dst,
void Gecko_DestroyShapeSource(mozilla::StyleShapeSource* shape);
void Gecko_NewBasicShape(mozilla::StyleShapeSource* shape,
mozilla::StyleBasicShapeType type);
void Gecko_NewShapeImage(mozilla::StyleShapeSource* shape);
void Gecko_StyleShapeSource_SetURLValue(mozilla::StyleShapeSource* shape,

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

@ -473,6 +473,7 @@ cbindgen-types = [
{ gecko = "StyleGenericGradientItem", servo = "values::generics::image::GradientItem" },
{ gecko = "StyleGenericVerticalAlign", servo = "values::generics::box_::VerticalAlign" },
{ gecko = "StyleVerticalAlignKeyword", servo = "values::generics::box_::VerticalAlignKeyword" },
{ gecko = "StyleGenericBasicShape", servo = "values::generics::basic_shape::BasicShape" },
]
mapped-generic-types = [

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

@ -18,6 +18,8 @@
# include "nsColor.h"
# include "nsCoord.h"
# include "mozilla/AtomArray.h"
# include "mozilla/IntegerRange.h"
# include "mozilla/Span.h"
# include "Units.h"
# include "mozilla/gfx/Types.h"
# include "mozilla/MemoryReporting.h"

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

@ -383,11 +383,6 @@ const KTableEntry nsCSSProps::kTextOverflowKTable[] = {
// keyword tables for SVG properties
const KTableEntry nsCSSProps::kShapeRadiusKTable[] = {
{eCSSKeyword_closest_side, StyleShapeRadius::ClosestSide},
{eCSSKeyword_farthest_side, StyleShapeRadius::FarthestSide},
{eCSSKeyword_UNKNOWN, -1}};
const KTableEntry nsCSSProps::kFilterFunctionKTable[] = {
{eCSSKeyword_blur, NS_STYLE_FILTER_BLUR},
{eCSSKeyword_brightness, NS_STYLE_FILTER_BRIGHTNESS},

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

@ -2565,140 +2565,6 @@ already_AddRefed<CSSValue> nsComputedDOMStyle::GetTransformValue(
return MatrixToCSSValue(matrix);
}
void nsComputedDOMStyle::BoxValuesToString(
nsAString& aString, const nsTArray<nsStyleCoord>& aBoxValues,
bool aClampNegativeCalc) {
MOZ_ASSERT(aBoxValues.Length() == 4, "wrong number of box values");
nsAutoString value1, value2, value3, value4;
SetCssTextToCoord(value1, aBoxValues[0], aClampNegativeCalc);
SetCssTextToCoord(value2, aBoxValues[1], aClampNegativeCalc);
SetCssTextToCoord(value3, aBoxValues[2], aClampNegativeCalc);
SetCssTextToCoord(value4, aBoxValues[3], aClampNegativeCalc);
// nsROCSSPrimitiveValue do not have binary comparison operators.
// Compare string results instead.
aString.Append(value1);
if (value1 != value2 || value1 != value3 || value1 != value4) {
aString.Append(' ');
aString.Append(value2);
if (value1 != value3 || value2 != value4) {
aString.Append(' ');
aString.Append(value3);
if (value2 != value4) {
aString.Append(' ');
aString.Append(value4);
}
}
}
}
void nsComputedDOMStyle::BasicShapeRadiiToString(nsAString& aCssText,
const BorderRadius& aCorners) {
Servo_SerializeBorderRadius(&aCorners, &aCssText);
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
const UniquePtr<StyleBasicShape>& aStyleBasicShape) {
MOZ_ASSERT(aStyleBasicShape, "Expect a valid basic shape pointer!");
StyleBasicShapeType type = aStyleBasicShape->GetShapeType();
// Shape function name and opening parenthesis.
nsAutoString shapeFunctionString;
AppendASCIItoUTF16(
nsCSSKeywords::GetStringValue(aStyleBasicShape->GetShapeTypeName()),
shapeFunctionString);
shapeFunctionString.Append('(');
switch (type) {
case StyleBasicShapeType::Polygon: {
bool hasEvenOdd =
aStyleBasicShape->GetFillRule() == StyleFillRule::Evenodd;
if (hasEvenOdd) {
shapeFunctionString.AppendLiteral("evenodd");
}
for (size_t i = 0; i < aStyleBasicShape->Coordinates().Length(); i += 2) {
nsAutoString coordString;
if (i > 0 || hasEvenOdd) {
shapeFunctionString.AppendLiteral(", ");
}
SetCssTextToCoord(coordString, aStyleBasicShape->Coordinates()[i],
false);
shapeFunctionString.Append(coordString);
shapeFunctionString.Append(' ');
SetCssTextToCoord(coordString, aStyleBasicShape->Coordinates()[i + 1],
false);
shapeFunctionString.Append(coordString);
}
break;
}
case StyleBasicShapeType::Circle:
case StyleBasicShapeType::Ellipse: {
const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
MOZ_ASSERT(
radii.Length() == (type == StyleBasicShapeType::Circle ? 1 : 2),
"wrong number of radii");
for (size_t i = 0; i < radii.Length(); ++i) {
nsAutoString radius;
RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
bool clampNegativeCalc = true;
SetValueToCoord(value, radii[i], clampNegativeCalc, nullptr,
nsCSSProps::kShapeRadiusKTable);
value->GetCssText(radius);
shapeFunctionString.Append(radius);
shapeFunctionString.Append(' ');
}
shapeFunctionString.AppendLiteral("at ");
RefPtr<nsDOMCSSValueList> position = GetROCSSValueList(false);
nsAutoString positionString;
SetValueToPosition(aStyleBasicShape->GetPosition(), position);
position->GetCssText(positionString);
shapeFunctionString.Append(positionString);
break;
}
case StyleBasicShapeType::Inset: {
BoxValuesToString(shapeFunctionString, aStyleBasicShape->Coordinates(),
false);
if (aStyleBasicShape->HasRadius()) {
shapeFunctionString.AppendLiteral(" round ");
nsAutoString radiiString;
BasicShapeRadiiToString(radiiString, aStyleBasicShape->GetRadius());
shapeFunctionString.Append(radiiString);
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("unexpected type");
}
shapeFunctionString.Append(')');
RefPtr<nsROCSSPrimitiveValue> functionValue = new nsROCSSPrimitiveValue;
functionValue->SetString(shapeFunctionString);
return functionValue.forget();
}
template <typename ReferenceBox>
already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForShapeSource(
const UniquePtr<StyleBasicShape>& aStyleBasicShape,
ReferenceBox aReferenceBox, const KTableEntry aBoxKeywordTable[]) {
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
if (aStyleBasicShape) {
valueList->AppendCSSValue(
CreatePrimitiveValueForBasicShape(aStyleBasicShape));
}
if (aReferenceBox == ReferenceBox::NoBox) {
return valueList.forget();
}
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(aReferenceBox, aBoxKeywordTable));
valueList->AppendCSSValue(val.forget());
return valueList.forget();
}
void nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
const nsStyleCoord& aCoord,
bool aClampNegativeCalc) {

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

@ -375,20 +375,6 @@ class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord,
bool aClampNegativeCalc);
template <typename ReferenceBox>
already_AddRefed<CSSValue> CreatePrimitiveValueForShapeSource(
const mozilla::UniquePtr<mozilla::StyleBasicShape>& aStyleBasicShape,
ReferenceBox aReferenceBox, const KTableEntry aBoxKeywordTable[]);
// Helper function for computing basic shape styles.
already_AddRefed<CSSValue> CreatePrimitiveValueForBasicShape(
const mozilla::UniquePtr<mozilla::StyleBasicShape>& aStyleBasicShape);
void BoxValuesToString(nsAString& aString,
const nsTArray<nsStyleCoord>& aBoxValues,
bool aClampNegativeCalc);
void BasicShapeRadiiToString(nsAString& aCssText,
const mozilla::BorderRadius&);
// Find out if we can safely skip flushing (i.e. pending restyles do not
// affect mElement).
bool NeedsToFlush() const;

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

@ -168,12 +168,6 @@ enum class StyleScrollbarWidth : uint8_t {
None,
};
// <shape-radius> for <basic-shape>
enum class StyleShapeRadius : uint8_t {
ClosestSide,
FarthestSide,
};
// Shape source type
enum class StyleShapeSourceType : uint8_t {
None,

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

@ -810,30 +810,6 @@ nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const {
return hint;
}
// --------------------
// StyleBasicShape
StyleBasicShape::StyleBasicShape(StyleBasicShapeType aType)
: mType(aType),
mFillRule(StyleFillRule::Nonzero),
mPosition(Position::FromPercentage(0.5f)),
mRadius(ZeroBorderRadius()) {}
nsCSSKeyword StyleBasicShape::GetShapeTypeName() const {
switch (mType) {
case StyleBasicShapeType::Polygon:
return eCSSKeyword_polygon;
case StyleBasicShapeType::Circle:
return eCSSKeyword_circle;
case StyleBasicShapeType::Ellipse:
return eCSSKeyword_ellipse;
case StyleBasicShapeType::Inset:
return eCSSKeyword_inset;
}
MOZ_ASSERT_UNREACHABLE("unexpected type");
return eCSSKeyword_UNKNOWN;
}
// --------------------
// StyleShapeSource
StyleShapeSource::StyleShapeSource() : mBasicShape() {}
@ -957,10 +933,13 @@ void StyleShapeSource::DoCopy(const StyleShapeSource& aOther) {
SetShapeImage(MakeUnique<nsStyleImage>(aOther.ShapeImage()));
break;
case StyleShapeSourceType::Shape:
SetBasicShape(MakeUnique<StyleBasicShape>(aOther.BasicShape()),
aOther.GetReferenceBox());
case StyleShapeSourceType::Shape: {
UniquePtr<StyleBasicShape> shape(Servo_CloneBasicShape(&aOther.BasicShape()));
// TODO(emilio): This could be a copy-ctor call like above if we teach
// cbindgen to generate copy-constructors for tagged unions.
SetBasicShape(std::move(shape), aOther.GetReferenceBox());
break;
}
case StyleShapeSourceType::Box:
SetReferenceBox(aOther.GetReferenceBox());

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

@ -1663,65 +1663,6 @@ struct StyleAnimation {
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
};
class StyleBasicShape final {
public:
explicit StyleBasicShape(StyleBasicShapeType);
StyleBasicShapeType GetShapeType() const { return mType; }
nsCSSKeyword GetShapeTypeName() const;
StyleFillRule GetFillRule() const { return mFillRule; }
const mozilla::Position& GetPosition() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Circle ||
mType == StyleBasicShapeType::Ellipse,
"expected circle or ellipse");
return mPosition;
}
bool HasRadius() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
NS_FOR_CSS_HALF_CORNERS(corner) {
auto& radius = mRadius.Get(corner);
if (radius.HasPercent() || radius.LengthInCSSPixels() != 0.0f) {
return true;
}
}
return false;
}
const mozilla::StyleBorderRadius& GetRadius() const {
MOZ_ASSERT(mType == StyleBasicShapeType::Inset, "expected inset");
return mRadius;
}
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
const nsTArray<nsStyleCoord>& Coordinates() const { return mCoordinates; }
bool operator==(const StyleBasicShape& aOther) const {
return mType == aOther.mType && mFillRule == aOther.mFillRule &&
mCoordinates == aOther.mCoordinates &&
mPosition == aOther.mPosition && mRadius == aOther.mRadius;
}
bool operator!=(const StyleBasicShape& aOther) const {
return !(*this == aOther);
}
private:
StyleBasicShapeType mType;
StyleFillRule mFillRule;
// mCoordinates has coordinates for polygon or radii for
// ellipse and circle.
// (top, right, bottom, left) for inset
nsTArray<nsStyleCoord> mCoordinates;
// position of center for ellipse or circle
mozilla::Position mPosition;
// corner radii for inset (0 if not set)
mozilla::StyleBorderRadius mRadius;
};
struct StyleSVGPath final {
const nsTArray<StylePathCommand>& Path() const { return mPath; }
@ -1779,14 +1720,14 @@ struct StyleShapeSource final {
void SetShapeImage(UniquePtr<nsStyleImage> aShapeImage);
const StyleBasicShape& BasicShape() const {
const mozilla::StyleBasicShape& BasicShape() const {
MOZ_ASSERT(mType == StyleShapeSourceType::Shape,
"Wrong shape source type!");
MOZ_ASSERT(mBasicShape);
return *mBasicShape;
}
void SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
void SetBasicShape(UniquePtr<mozilla::StyleBasicShape> aBasicShape,
StyleGeometryBox aReferenceBox);
StyleGeometryBox GetReferenceBox() const {
@ -1815,7 +1756,7 @@ struct StyleShapeSource final {
void DoDestroy();
union {
mozilla::UniquePtr<StyleBasicShape> mBasicShape;
mozilla::UniquePtr<mozilla::StyleBasicShape> mBasicShape;
mozilla::UniquePtr<nsStyleImage> mShapeImage;
mozilla::UniquePtr<StyleSVGPath> mSVGPath;
// TODO: Bug 1480665, implement ray() function.
@ -2727,6 +2668,7 @@ class nsStyleSVGPaint {
mozilla::StyleColor mColor;
mozilla::css::URLValue* mPaintServer;
explicit ColorOrPaintServer(mozilla::StyleColor c) : mColor(c) {}
~ColorOrPaintServer() {} // Caller must call Reset().
};
ColorOrPaintServer mPaint;
nsStyleSVGPaintType mType;

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

@ -116,14 +116,14 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPath(
r = ToAppUnits(r.ToNearestPixels(appUnitsPerDevPixel), appUnitsPerDevPixel);
const auto& basicShape = mClipPathStyle.BasicShape();
switch (basicShape.GetShapeType()) {
case StyleBasicShapeType::Circle:
switch (basicShape.tag) {
case StyleBasicShape::Tag::Circle:
return CreateClipPathCircle(aDrawTarget, r);
case StyleBasicShapeType::Ellipse:
case StyleBasicShape::Tag::Ellipse:
return CreateClipPathEllipse(aDrawTarget, r);
case StyleBasicShapeType::Polygon:
case StyleBasicShape::Tag::Polygon:
return CreateClipPathPolygon(aDrawTarget, r);
case StyleBasicShapeType::Inset:
case StyleBasicShape::Tag::Inset:
return CreateClipPathInset(aDrawTarget, r);
break;
default:
@ -172,7 +172,7 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathEllipse(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathPolygon(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& basicShape = mClipPathStyle.BasicShape();
auto fillRule = basicShape.GetFillRule() == StyleFillRule::Nonzero
auto fillRule = basicShape.AsPolygon().fill == StyleFillRule::Nonzero
? FillRule::FILL_WINDING
: FillRule::FILL_EVEN_ODD;
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(fillRule);

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

@ -182,7 +182,7 @@ bool nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(
}
const auto& shape = clipPath.BasicShape();
return (shape.GetShapeType() != StyleBasicShapeType::Polygon);
return !shape.IsPolygon();
}
nsPoint nsSVGIntegrationUtils::GetOffsetToBoundingBox(nsIFrame* aFrame) {

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

@ -532,28 +532,17 @@ impl nsStyleImage {
pub mod basic_shape {
//! Conversions from and to CSS shape representations.
use crate::gecko::values::GeckoStyleCoordConvertible;
use crate::gecko_bindings::structs::nsStyleCoord;
use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType};
use crate::gecko_bindings::structs::{
StyleGeometryBox, StyleShapeSource, StyleShapeSourceType,
};
use crate::gecko_bindings::sugar::refptr::RefPtr;
use crate::values::computed::basic_shape::{
BasicShape, ClippingShape, FloatAreaShape, ShapeRadius,
BasicShape, ClippingShape, FloatAreaShape,
};
use crate::values::computed::length::LengthPercentage;
use crate::values::computed::motion::OffsetPath;
use crate::values::computed::url::ComputedUrl;
use crate::values::generics::basic_shape::{
BasicShape as GenericBasicShape, InsetRect, Polygon,
};
use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord};
use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource};
use crate::values::generics::rect::Rect;
use crate::values::generics::basic_shape::{Path, GeometryBox, ShapeBox, ShapeSource};
use crate::values::specified::SVGPathData;
use std::borrow::Borrow;
impl StyleShapeSource {
/// Convert StyleShapeSource to ShapeSource except URL and Image
@ -569,7 +558,7 @@ pub mod basic_shape {
StyleShapeSourceType::Box => Some(ShapeSource::Box(self.mReferenceBox.into())),
StyleShapeSourceType::Shape => {
let other_shape = unsafe { &*self.__bindgen_anon_1.mBasicShape.as_ref().mPtr };
let shape = other_shape.into();
let shape = Box::new(other_shape.clone());
let reference_box = if self.mReferenceBox == StyleGeometryBox::NoBox {
None
} else {
@ -653,67 +642,6 @@ pub mod basic_shape {
}
}
impl<'a> From<&'a StyleBasicShape> for BasicShape {
fn from(other: &'a StyleBasicShape) -> Self {
match other.mType {
StyleBasicShapeType::Inset => {
let t = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[0]);
let r = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[1]);
let b = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[2]);
let l = LengthPercentage::from_gecko_style_coord(&other.mCoordinates[3]);
let round = other.mRadius;
let rect = Rect::new(
t.expect("inset() offset should be a length, percentage, or calc value"),
r.expect("inset() offset should be a length, percentage, or calc value"),
b.expect("inset() offset should be a length, percentage, or calc value"),
l.expect("inset() offset should be a length, percentage, or calc value"),
);
GenericBasicShape::Inset(InsetRect { rect, round })
},
StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle {
radius: (&other.mCoordinates[0]).into(),
position: other.mPosition,
}),
StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse {
semiaxis_x: (&other.mCoordinates[0]).into(),
semiaxis_y: (&other.mCoordinates[1]).into(),
position: other.mPosition,
}),
StyleBasicShapeType::Polygon => {
let mut coords = Vec::with_capacity(other.mCoordinates.len() / 2);
for i in 0..(other.mCoordinates.len() / 2) {
let x = 2 * i;
let y = x + 1;
coords.push(PolygonCoord(
LengthPercentage::from_gecko_style_coord(&other.mCoordinates[x])
.expect(
"polygon() coordinate should be a length, percentage, \
or calc value",
),
LengthPercentage::from_gecko_style_coord(&other.mCoordinates[y])
.expect(
"polygon() coordinate should be a length, percentage, \
or calc value",
),
))
}
GenericBasicShape::Polygon(Polygon {
fill: other.mFillRule,
coordinates: coords,
})
},
}
}
}
impl<'a> From<&'a nsStyleCoord> for ShapeRadius {
fn from(other: &'a nsStyleCoord) -> Self {
let other = other.borrow();
ShapeRadius::from_gecko_style_coord(other)
.expect("<shape-radius> should be a length, percentage, calc, or keyword value")
}
}
impl From<ShapeBox> for StyleGeometryBox {
fn from(reference: ShapeBox) -> Self {
use crate::gecko_bindings::structs::StyleGeometryBox::*;

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

@ -8,12 +8,10 @@
use crate::counter_style::{Symbol, Symbols};
use crate::gecko_bindings::structs::{nsStyleCoord, CounterStylePtr};
use crate::gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius};
use crate::gecko_bindings::structs::StyleGridTrackBreadth;
use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius;
use crate::values::computed::{Angle, Length, LengthPercentage};
use crate::values::computed::{Number, NumberOrPercentage, Percentage};
use crate::values::generics::basic_shape::ShapeRadius;
use crate::values::generics::gecko::ScrollSnapPoint;
use crate::values::generics::grid::{TrackBreadth, TrackKeyword};
use crate::values::generics::length::LengthPercentageOrAuto;
@ -192,35 +190,6 @@ impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<
}
}
impl GeckoStyleCoordConvertible for ComputedShapeRadius {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
match *self {
ShapeRadius::ClosestSide => coord.set_value(CoordDataValue::Enumerated(
StyleShapeRadius::ClosestSide as u32,
)),
ShapeRadius::FarthestSide => coord.set_value(CoordDataValue::Enumerated(
StyleShapeRadius::FarthestSide as u32,
)),
ShapeRadius::Length(lp) => lp.to_gecko_style_coord(coord),
}
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Enumerated(v) => {
if v == StyleShapeRadius::ClosestSide as u32 {
Some(ShapeRadius::ClosestSide)
} else if v == StyleShapeRadius::FarthestSide as u32 {
Some(ShapeRadius::FarthestSide)
} else {
None
}
},
_ => GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length),
}
}
}
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
if let Some(ref me) = *self {

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

@ -20,6 +20,9 @@ use to_shmem::{SharedMemoryBuilder, ToShmem};
///
/// But handling fat pointers with cbindgen both in structs and argument
/// positions more generally is a bit tricky.
///
/// cbindgen:derive-eq=false
/// cbindgen:derive-neq=false
#[repr(C)]
pub struct OwnedSlice<T: Sized> {
ptr: NonNull<T>,

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

@ -4046,16 +4046,15 @@ fn set_style_svg_path(
<%def name="impl_shape_source(ident, gecko_ffi_name)">
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use crate::gecko_bindings::bindings::{Gecko_NewBasicShape, Gecko_DestroyShapeSource};
use crate::gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleShapeSourceType};
use crate::gecko_bindings::structs::{StyleGeometryBox, StyleShapeSource};
use crate::gecko::values::GeckoStyleCoordConvertible;
use crate::values::generics::basic_shape::{BasicShape, ShapeSource};
use crate::values::generics::basic_shape::ShapeSource;
use crate::gecko_bindings::structs::StyleShapeSourceType;
use crate::gecko_bindings::structs::StyleGeometryBox;
let ref mut ${ident} = self.gecko.${gecko_ffi_name};
// clean up existing struct
unsafe { Gecko_DestroyShapeSource(${ident}) };
// clean up existing struct.
unsafe { bindings::Gecko_DestroyShapeSource(${ident}) };
${ident}.mType = StyleShapeSourceType::None;
match v {
@ -4084,72 +4083,12 @@ fn set_style_svg_path(
}
ShapeSource::Path(p) => set_style_svg_path(${ident}, &p.path, p.fill),
ShapeSource::Shape(servo_shape, maybe_box) => {
fn init_shape(${ident}: &mut StyleShapeSource, basic_shape_type: StyleBasicShapeType)
-> &mut StyleBasicShape {
unsafe {
// Create StyleBasicShape in StyleShapeSource. mReferenceBox and mType
// will be set manually later.
Gecko_NewBasicShape(${ident}, basic_shape_type);
&mut *${ident}.__bindgen_anon_1.mBasicShape.as_mut().mPtr
}
unsafe {
${ident}.__bindgen_anon_1.mBasicShape.as_mut().mPtr =
Box::into_raw(servo_shape);
}
match servo_shape {
BasicShape::Inset(inset) => {
let shape = init_shape(${ident}, StyleBasicShapeType::Inset);
unsafe { shape.mCoordinates.set_len(4) };
// set_len() can't call constructors, so the coordinates
// can contain any value. set_value() attempts to free
// allocated coordinates, so we don't want to feed it
// garbage values which it may misinterpret.
// Instead, we use leaky_set_value to blindly overwrite
// the garbage data without
// attempting to clean up.
shape.mCoordinates[0].leaky_set_null();
inset.rect.0.to_gecko_style_coord(&mut shape.mCoordinates[0]);
shape.mCoordinates[1].leaky_set_null();
inset.rect.1.to_gecko_style_coord(&mut shape.mCoordinates[1]);
shape.mCoordinates[2].leaky_set_null();
inset.rect.2.to_gecko_style_coord(&mut shape.mCoordinates[2]);
shape.mCoordinates[3].leaky_set_null();
inset.rect.3.to_gecko_style_coord(&mut shape.mCoordinates[3]);
shape.mRadius = inset.round;
}
BasicShape::Circle(circ) => {
let shape = init_shape(${ident}, StyleBasicShapeType::Circle);
unsafe { shape.mCoordinates.set_len(1) };
shape.mCoordinates[0].leaky_set_null();
circ.radius.to_gecko_style_coord(&mut shape.mCoordinates[0]);
shape.mPosition = circ.position.into();
}
BasicShape::Ellipse(el) => {
let shape = init_shape(${ident}, StyleBasicShapeType::Ellipse);
unsafe { shape.mCoordinates.set_len(2) };
shape.mCoordinates[0].leaky_set_null();
el.semiaxis_x.to_gecko_style_coord(&mut shape.mCoordinates[0]);
shape.mCoordinates[1].leaky_set_null();
el.semiaxis_y.to_gecko_style_coord(&mut shape.mCoordinates[1]);
shape.mPosition = el.position.into();
}
BasicShape::Polygon(poly) => {
let shape = init_shape(${ident}, StyleBasicShapeType::Polygon);
unsafe {
shape.mCoordinates.set_len(poly.coordinates.len() as u32 * 2);
}
for (i, coord) in poly.coordinates.iter().enumerate() {
shape.mCoordinates[2 * i].leaky_set_null();
shape.mCoordinates[2 * i + 1].leaky_set_null();
coord.0.to_gecko_style_coord(&mut shape.mCoordinates[2 * i]);
coord.1.to_gecko_style_coord(&mut shape.mCoordinates[2 * i + 1]);
}
shape.mFillRule = poly.fill;
}
}
${ident}.mReferenceBox = maybe_box.map(Into::into)
.unwrap_or(StyleGeometryBox::NoBox);
${ident}.mReferenceBox =
maybe_box.map(Into::into).unwrap_or(StyleGeometryBox::NoBox);
${ident}.mType = StyleShapeSourceType::Shape;
}
}

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

@ -87,8 +87,8 @@ ${helpers.predefined_type(
"basic_shape::ClippingShape",
"generics::basic_shape::ShapeSource::None",
products="gecko",
boxed=True,
animation_value_type="basic_shape::ClippingShape",
boxed=True,
flags="CREATES_STACKING_CONTEXT",
spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path",
)}

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

@ -16,7 +16,6 @@ use crate::values::computed::Image;
use crate::values::specified::SVGPathData;
use crate::values::CSSFloat;
use app_units::Au;
use euclid::Point2D;
use smallvec::SmallVec;
use std::cmp;
@ -241,16 +240,10 @@ impl Animate for Au {
}
}
impl<T> Animate for Point2D<T>
where
T: Animate,
{
impl<T: Animate> Animate for Box<T> {
#[inline]
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
Ok(Point2D::new(
self.x.animate(&other.x, procedure)?,
self.y.animate(&other.y, procedure)?,
))
Ok(Box::new((**self).animate(&other, procedure)?))
}
}
@ -288,6 +281,24 @@ where
}
}
impl<T> ToAnimatedValue for Box<T>
where
T: ToAnimatedValue,
{
type AnimatedValue = Box<<T as ToAnimatedValue>::AnimatedValue>;
#[inline]
fn to_animated_value(self) -> Self::AnimatedValue {
Box::new((*self).to_animated_value())
}
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
Box::new(T::from_animated_value(*animated))
}
}
impl<T> ToAnimatedValue for Box<[T]>
where
T: ToAnimatedValue,
@ -328,7 +339,7 @@ where
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
Box::from_animated_value(animated.into_box()).into()
Self::from(Box::from_animated_value(animated.into_box()))
}
}

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

@ -23,7 +23,7 @@ pub type ClippingShape = generic::ClippingShape<BasicShape, ComputedUrl>;
pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
/// A computed basic shape.
pub type BasicShape = generic::BasicShape<
pub type BasicShape = generic::GenericBasicShape<
LengthPercentage,
LengthPercentage,
LengthPercentage,
@ -41,7 +41,7 @@ pub type Ellipse =
generic::Ellipse<LengthPercentage, LengthPercentage, NonNegativeLengthPercentage>;
/// The computed value of `ShapeRadius`
pub type ShapeRadius = generic::ShapeRadius<NonNegativeLengthPercentage>;
pub type ShapeRadius = generic::GenericShapeRadius<NonNegativeLengthPercentage>;
impl ToCss for Circle {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result

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

@ -7,8 +7,8 @@
use crate::values::animated::{Animate, Procedure, ToAnimatedZero};
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::border::BorderRadius;
use crate::values::generics::position::Position;
use crate::values::generics::border::GenericBorderRadius;
use crate::values::generics::position::GenericPosition;
use crate::values::generics::rect::Rect;
use crate::values::specified::SVGPathData;
use crate::Zero;
@ -89,7 +89,7 @@ pub enum ShapeBox {
pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
#[animation(error)]
ImageOrUrl(ImageOrUrl),
Shape(BasicShape, Option<ReferenceBox>),
Shape(Box<BasicShape>, Option<ReferenceBox>),
#[animation(error)]
Box(ReferenceBox),
#[css(function)]
@ -113,7 +113,8 @@ pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
ToResolvedValue,
ToShmem,
)]
pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
#[repr(C, u8)]
pub enum GenericBasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
Inset(
#[css(field_bound)]
#[shmem(field_bound)]
@ -129,9 +130,11 @@ pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
#[shmem(field_bound)]
Ellipse<H, V, NonNegativeLengthPercentage>,
),
Polygon(Polygon<LengthPercentage>),
Polygon(GenericPolygon<LengthPercentage>),
}
pub use self::GenericBasicShape as BasicShape;
/// <https://drafts.csswg.org/css-shapes/#funcdef-inset>
#[allow(missing_docs)]
#[css(function = "inset")]
@ -148,10 +151,11 @@ pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct InsetRect<LengthPercentage, NonNegativeLengthPercentage> {
pub rect: Rect<LengthPercentage>,
#[shmem(field_bound)]
pub round: BorderRadius<NonNegativeLengthPercentage>,
pub round: GenericBorderRadius<NonNegativeLengthPercentage>,
}
/// <https://drafts.csswg.org/css-shapes/#funcdef-circle>
@ -171,9 +175,10 @@ pub struct InsetRect<LengthPercentage, NonNegativeLengthPercentage> {
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct Circle<H, V, NonNegativeLengthPercentage> {
pub position: Position<H, V>,
pub radius: ShapeRadius<NonNegativeLengthPercentage>,
pub position: GenericPosition<H, V>,
pub radius: GenericShapeRadius<NonNegativeLengthPercentage>,
}
/// <https://drafts.csswg.org/css-shapes/#funcdef-ellipse>
@ -193,10 +198,11 @@ pub struct Circle<H, V, NonNegativeLengthPercentage> {
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct Ellipse<H, V, NonNegativeLengthPercentage> {
pub position: Position<H, V>,
pub semiaxis_x: ShapeRadius<NonNegativeLengthPercentage>,
pub semiaxis_y: ShapeRadius<NonNegativeLengthPercentage>,
pub position: GenericPosition<H, V>,
pub semiaxis_x: GenericShapeRadius<NonNegativeLengthPercentage>,
pub semiaxis_y: GenericShapeRadius<NonNegativeLengthPercentage>,
}
/// <https://drafts.csswg.org/css-shapes/#typedef-shape-radius>
@ -216,7 +222,8 @@ pub struct Ellipse<H, V, NonNegativeLengthPercentage> {
ToResolvedValue,
ToShmem,
)]
pub enum ShapeRadius<NonNegativeLengthPercentage> {
#[repr(C, u8)]
pub enum GenericShapeRadius<NonNegativeLengthPercentage> {
Length(NonNegativeLengthPercentage),
#[animation(error)]
ClosestSide,
@ -224,10 +231,12 @@ pub enum ShapeRadius<NonNegativeLengthPercentage> {
FarthestSide,
}
pub use self::GenericShapeRadius as ShapeRadius;
/// A generic type for representing the `polygon()` function
///
/// <https://drafts.csswg.org/css-shapes/#funcdef-polygon>
#[css(comma, function)]
#[css(comma, function = "polygon")]
#[derive(
Clone,
Debug,
@ -240,15 +249,18 @@ pub enum ShapeRadius<NonNegativeLengthPercentage> {
ToResolvedValue,
ToShmem,
)]
pub struct Polygon<LengthPercentage> {
#[repr(C)]
pub struct GenericPolygon<LengthPercentage> {
/// The filling rule for a polygon.
#[css(skip_if = "fill_is_default")]
pub fill: FillRule,
/// A collection of (x, y) coordinates to draw the polygon.
#[css(iterable)]
pub coordinates: Vec<PolygonCoord<LengthPercentage>>,
pub coordinates: crate::OwnedSlice<PolygonCoord<LengthPercentage>>,
}
pub use self::GenericPolygon as Polygon;
/// Coordinates for Polygon.
#[derive(
Clone,
@ -262,6 +274,7 @@ pub struct Polygon<LengthPercentage> {
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct PolygonCoord<LengthPercentage>(pub LengthPercentage, pub LengthPercentage);
// https://drafts.csswg.org/css-shapes/#typedef-fill-rule
@ -393,7 +406,8 @@ where
this.1.animate(&other.1, procedure)?,
))
})
.collect::<Result<Vec<_>, _>>()?;
.collect::<Result<Vec<_>, _>>()?
.into();
Ok(Polygon {
fill: self.fill,
coordinates,

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

@ -55,7 +55,7 @@ pub type Ellipse =
pub type ShapeRadius = generic::ShapeRadius<NonNegativeLengthPercentage>;
/// The specified value of `Polygon`
pub type Polygon = generic::Polygon<LengthPercentage>;
pub type Polygon = generic::GenericPolygon<LengthPercentage>;
#[cfg(feature = "gecko")]
fn is_clip_path_path_enabled(context: &ParserContext) -> bool {
@ -138,11 +138,11 @@ where
}
if let Some(shp) = shape {
return Ok(ShapeSource::Shape(shp, ref_box));
return Ok(ShapeSource::Shape(Box::new(shp), ref_box));
}
ref_box
.map(|v| ShapeSource::Box(v))
.map(ShapeSource::Box)
.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
@ -152,7 +152,7 @@ impl Parse for GeometryBox {
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
if let Ok(shape_box) = input.try(|i| ShapeBox::parse(i)) {
if let Ok(shape_box) = input.try(ShapeBox::parse) {
return Ok(GeometryBox::ShapeBox(shape_box));
}
@ -352,17 +352,14 @@ impl Polygon {
})
.unwrap_or_default();
let buf = input.parse_comma_separated(|i| {
let coordinates = input.parse_comma_separated(|i| {
Ok(PolygonCoord(
LengthPercentage::parse(context, i)?,
LengthPercentage::parse(context, i)?,
))
})?;
})?.into();
Ok(Polygon {
fill: fill,
coordinates: buf,
})
Ok(Polygon { fill, coordinates })
}
}

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

@ -38,6 +38,7 @@ bitflags = true
[enum]
derive_helper_methods = true
derive_const_casts = true
derive_tagged_enum_destructor = true
cast_assert_name = "MOZ_ASSERT"
[export]
@ -118,6 +119,8 @@ include = [
"ColorOrAuto",
"GradientItem",
"VerticalAlign",
"BasicShape",
"ShapeRadius",
]
item_types = ["enums", "structs", "typedefs", "functions"]
renaming_overrides_prefixing = true
@ -331,3 +334,40 @@ renaming_overrides_prefixing = true
inline nscolor ToColor() const;
"""
"OwnedSlice" = """
StyleOwnedSlice() :
ptr((T*)alignof(T)),
len(0) {}
// NOTE(emilio): Could be implemented with some effort, but for now no copy.
StyleOwnedSlice(const StyleOwnedSlice& aOther) = delete;
~StyleOwnedSlice() {
if (!len) {
return;
}
for (size_t i : IntegerRange(len)) {
ptr[i].~T();
}
free(ptr);
ptr = (T*)alignof(T);
len = 0;
}
Span<const T> AsSpan() const {
return MakeSpan(ptr, len);
}
size_t Length() const {
return AsSpan().Length();
}
bool operator==(const StyleOwnedSlice& other) const {
return AsSpan() == other.AsSpan();
}
bool operator!=(const StyleOwnedSlice& other) const {
return !(*this == other);
}
"""

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

@ -6402,3 +6402,12 @@ pub unsafe extern "C" fn Servo_SharedMemoryBuilder_Drop(
) {
SharedMemoryBuilder::drop_ffi(builder)
}
/// Returns a unique pointer to a clone of the shape image.
///
/// Probably temporary, as we move more stuff to cbindgen.
#[no_mangle]
#[must_use]
pub unsafe extern "C" fn Servo_CloneBasicShape(v: &computed::basic_shape::BasicShape) -> *mut computed::basic_shape::BasicShape {
Box::into_raw(Box::new(v.clone()))
}

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

@ -1,4 +0,0 @@
[shape-outside-computed.html]
[Property shape-outside value 'circle(calc(10px - 0.5em) at 50% -50%) border-box' computes to 'circle(0px at 50% -50%) border-box']
expected: FAIL

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

@ -2,9 +2,6 @@
[test unit: cm - circle(50cm) - computed]
expected: FAIL
[test unit: mm - circle(50mm) - computed]
expected: FAIL
[test unit: ex - circle(50ex) - computed]
expected:
if os == "win": PASS

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

@ -1,6 +1,4 @@
[shape-outside-circle-006.html]
[circle(+20.340px) - computed]
expected: FAIL
[circle(+10px) - inline]
expected: FAIL

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

@ -98,39 +98,15 @@
[test unit: cm - ellipse(closest-side 75cm) - computed]
expected: FAIL
[test unit: cm - ellipse(25cm farthest-side) - computed]
expected: FAIL
[test unit: cm - ellipse(farthest-side 75cm) - computed]
expected: FAIL
[test unit: mm - ellipse(50mm) - computed]
expected: FAIL
[test unit: mm - ellipse(50mm 100mm) - computed]
expected: FAIL
[test unit: mm - ellipse(100mm 100px) - computed]
expected: FAIL
[test unit: mm - ellipse(50mm 25%) - computed]
expected: FAIL
[test unit: mm - ellipse(25% 50mm) - computed]
expected: FAIL
[test unit: mm - ellipse(25mm closest-side) - computed]
expected: FAIL
[test unit: mm - ellipse(closest-side 75mm) - computed]
expected: FAIL
[test unit: mm - ellipse(25mm farthest-side) - computed]
expected: FAIL
[test unit: mm - ellipse(farthest-side 75mm) - computed]
expected: FAIL
[test unit: in - ellipse(50in) - computed]
expected: FAIL

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

@ -1,7 +1,4 @@
[shape-outside-ellipse-006.html]
[ellipse(+10.00px +20.230px) - computed]
expected: FAIL
[ellipse(+30.00px 40.567px) - inline]
expected: FAIL

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

@ -1,34 +1,13 @@
[shape-outside-inset-001.html]
[One arg - cm - computed]
expected: FAIL
[Two args - cm cm - computed]
expected: FAIL
[Two args - cm % - computed]
expected: FAIL
[Two args - % cm - computed]
expected: FAIL
[Three args - cm cm cm - computed]
expected: FAIL
[Three args - cm cm % - computed]
expected: FAIL
[Three args - cm % cm - computed]
expected: FAIL
[Three args - cm % % - computed]
expected: FAIL
[Three args - % cm cm - computed]
expected: FAIL
[Three args - % cm % - computed]
expected: FAIL
[Three args - % % cm - computed]
expected: FAIL
@ -41,9 +20,6 @@
[Four args - cm cm % cm - computed]
expected: FAIL
[Four args - cm cm % % - computed]
expected: FAIL
[Four args - cm % cm cm - computed]
expected: FAIL
@ -53,9 +29,6 @@
[Four args - cm % % cm - computed]
expected: FAIL
[Four args - cm % % % - computed]
expected: FAIL
[Four args - % cm cm cm - computed]
expected: FAIL
@ -65,9 +38,6 @@
[Four args - % cm % cm - computed]
expected: FAIL
[Four args - % cm % % - computed]
expected: FAIL
[Four args - % % cm cm - computed]
expected: FAIL
@ -77,81 +47,3 @@
[Four args - % % % cm - computed]
expected: FAIL
[One arg - mm - computed]
expected: FAIL
[Two args - mm mm - computed]
expected: FAIL
[Two args - mm % - computed]
expected: FAIL
[Two args - % mm - computed]
expected: FAIL
[Three args - mm mm mm - computed]
expected: FAIL
[Three args - mm mm % - computed]
expected: FAIL
[Three args - mm % mm - computed]
expected: FAIL
[Three args - mm % % - computed]
expected: FAIL
[Three args - % mm mm - computed]
expected: FAIL
[Three args - % mm % - computed]
expected: FAIL
[Three args - % % mm - computed]
expected: FAIL
[Four args - mm mm mm mm - computed]
expected: FAIL
[Four args - mm mm mm % - computed]
expected: FAIL
[Four args - mm mm % mm - computed]
expected: FAIL
[Four args - mm mm % % - computed]
expected: FAIL
[Four args - mm % mm mm - computed]
expected: FAIL
[Four args - mm % mm % - computed]
expected: FAIL
[Four args - mm % % mm - computed]
expected: FAIL
[Four args - mm % % % - computed]
expected: FAIL
[Four args - % mm mm mm - computed]
expected: FAIL
[Four args - % mm mm % - computed]
expected: FAIL
[Four args - % mm % mm - computed]
expected: FAIL
[Four args - % mm % % - computed]
expected: FAIL
[Four args - % % mm mm - computed]
expected: FAIL
[Four args - % % mm % - computed]
expected: FAIL
[Four args - % % % mm - computed]
expected: FAIL

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

@ -1,28 +1,10 @@
[shape-outside-inset-003.html]
[inset(10cm round 10cm) - computed]
expected: FAIL
[inset(10cm round 10cm / 10cm) - computed]
expected: FAIL
[inset(10cm round 10cm / 10cm 20cm) - computed]
expected: FAIL
[inset(10cm round 10cm / 10cm 20cm 30cm) - computed]
expected: FAIL
[inset(10cm round 10cm / 10cm 20cm 30cm 40cm) - computed]
expected: FAIL
[inset(10cm round 10cm 20cm) - computed]
expected: FAIL
[inset(10cm round 10cm 20cm / 10cm) - computed]
expected: FAIL
[inset(10cm round 10cm 20cm / 10cm 20cm) - computed]
expected: FAIL
[inset(10cm round 10cm 20cm / 10cm 20cm 30cm) - computed]
expected: FAIL
@ -59,66 +41,6 @@
[inset(10cm round 10cm 20cm 30cm 40cm / 10cm 20cm 30cm 40cm) - computed]
expected: FAIL
[inset(10mm round 10mm) - computed]
expected: FAIL
[inset(10mm round 10mm / 10mm) - computed]
expected: FAIL
[inset(10mm round 10mm / 10mm 20mm) - computed]
expected: FAIL
[inset(10mm round 10mm / 10mm 20mm 30mm) - computed]
expected: FAIL
[inset(10mm round 10mm / 10mm 20mm 30mm 40mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm / 10mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm / 10mm 20mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm / 10mm 20mm 30mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm / 10mm 20mm 30mm 40mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm / 10mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm / 10mm 20mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm / 10mm 20mm 30mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm / 10mm 20mm 30mm 40mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm 40mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm 40mm / 10mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm 40mm / 10mm 20mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm 40mm / 10mm 20mm 30mm) - computed]
expected: FAIL
[inset(10mm round 10mm 20mm 30mm 40mm / 10mm 20mm 30mm 40mm) - computed]
expected: FAIL
[inset(10ex round 10ex) - computed]
expected:
if os == "win": PASS

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

@ -1,13 +0,0 @@
[shape-outside-inset-004.html]
[inset(10.1200px 20.34px 30.56px 40.780px) - computed]
expected: FAIL
[inset(10.123px 20.00px 30.10px 40.5678px) - computed]
expected: FAIL
[inset(+10.1200px -20.340px +30.56px -40.780px) - computed]
expected: FAIL
[inset(-10.123px +20.00px -30.10px +40.5678px) - computed]
expected: FAIL

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

@ -23,18 +23,9 @@
if (os == "android") and e10s: PASS
FAIL
[One vertex - cm cm - computed]
expected: FAIL
[One vertex - cm mm - computed]
expected: FAIL
[Two vertices - cm cm, cm cm - computed]
expected: FAIL
[Two vertices - cm cm, mm mm - computed]
expected: FAIL
[Two vertices - mm mm, cm cm - computed]
expected: FAIL
@ -44,12 +35,6 @@
[Three vertices - cm cm, cm cm, cm cm - computed]
expected: FAIL
[Three vertices - mm mm, mm mm, mm mm - computed]
expected: FAIL
[Three vertices - cm cm, mm mm, pc pc - computed]
expected: FAIL
[Three vertices - pc pc, cm, cm, mm mm - computed]
expected: FAIL

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

@ -1,7 +0,0 @@
[shape-outside-polygon-005.html]
[polygon(1.0px 2.22px, 3.40px 4.555px, 5.607px 6.99px) - computed]
expected: FAIL
[polygon(+1.0px -2.22px, +3.40px -4.550px, 5.67px -6.99px) - computed]
expected: FAIL

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

@ -13,6 +13,3 @@
if (os == "win") and (processor == "aarch64"): PASS
FAIL
[Fixed units - computed]
expected: FAIL