Bug 1614510 - Use cbindgen for shape-outside and clip-path. r=boris

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2020-02-11 22:03:53 +00:00
Родитель 90b8c7c6b2
Коммит 628f21dc90
20 изменённых файлов: 195 добавлений и 628 удалений

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

@ -9934,17 +9934,59 @@ static nsRect ComputeHTMLReferenceRect(nsIFrame* aFrame,
return r;
}
static StyleGeometryBox ShapeBoxToGeometryBox(const StyleShapeBox& aBox) {
switch (aBox) {
case StyleShapeBox::BorderBox:
return StyleGeometryBox::BorderBox;
case StyleShapeBox::ContentBox:
return StyleGeometryBox::ContentBox;
case StyleShapeBox::MarginBox:
return StyleGeometryBox::MarginBox;
case StyleShapeBox::PaddingBox:
return StyleGeometryBox::PaddingBox;
}
MOZ_ASSERT_UNREACHABLE("Unknown shape box type");
return StyleGeometryBox::MarginBox;
}
static StyleGeometryBox ClipPathBoxToGeometryBox(
const StyleShapeGeometryBox& aBox) {
using Tag = StyleShapeGeometryBox::Tag;
switch (aBox.tag) {
case Tag::ShapeBox:
return ShapeBoxToGeometryBox(aBox.AsShapeBox());
case Tag::ElementDependent:
return StyleGeometryBox::NoBox;
case Tag::FillBox:
return StyleGeometryBox::FillBox;
case Tag::StrokeBox:
return StyleGeometryBox::StrokeBox;
case Tag::ViewBox:
return StyleGeometryBox::ViewBox;
}
MOZ_ASSERT_UNREACHABLE("Unknown shape box type");
return StyleGeometryBox::NoBox;
}
/* static */
nsRect nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame,
StyleGeometryBox aGeometryBox) {
// We use ComputeSVGReferenceRect for all SVG elements, except <svg>
// element, which does have an associated CSS layout box. In this case we
// should still use ComputeHTMLReferenceRect for region computing.
nsRect r = (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)
? ComputeSVGReferenceRect(aFrame, aGeometryBox)
: ComputeHTMLReferenceRect(aFrame, aGeometryBox);
return aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT)
? ComputeSVGReferenceRect(aFrame, aGeometryBox)
: ComputeHTMLReferenceRect(aFrame, aGeometryBox);
}
return r;
nsRect nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame,
const StyleShapeBox& aBox) {
return ComputeGeometryBox(aFrame, ShapeBoxToGeometryBox(aBox));
}
nsRect nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame,
const StyleShapeGeometryBox& aBox) {
return ComputeGeometryBox(aFrame, ClipPathBoxToGeometryBox(aBox));
}
/* static */

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

@ -2942,8 +2942,12 @@ class nsLayoutUtils {
static bool IsInvisibleBreak(nsINode* aNode,
nsIFrame** aNextLineFrame = nullptr);
static nsRect ComputeGeometryBox(nsIFrame* aFrame,
StyleGeometryBox aGeometryBox);
static nsRect ComputeGeometryBox(nsIFrame*, StyleGeometryBox);
static nsRect ComputeGeometryBox(nsIFrame*,
const mozilla::StyleShapeGeometryBox&);
static nsRect ComputeGeometryBox(nsIFrame*, const mozilla::StyleShapeBox&);
static nsPoint ComputeOffsetToUserSpace(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);

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

@ -654,9 +654,9 @@ static nscoord FloatMarginISize(const ReflowInput& aCBReflowInput,
// Maybe all this code could be refactored to make this cleaner, but keeping the
// two properties separated was slightly nicer.
struct ShapeInvalidationData {
StyleShapeSource mShapeOutside;
StyleFloatAreaShape mShapeOutside{StyleFloatAreaShape::None()};
float mShapeImageThreshold = 0.0;
mozilla::LengthPercentage mShapeMargin;
LengthPercentage mShapeMargin;
ShapeInvalidationData() = default;
@ -665,7 +665,7 @@ struct ShapeInvalidationData {
}
static bool IsNeeded(const nsStyleDisplay& aDisplay) {
return aDisplay.mShapeOutside.GetType() != StyleShapeSourceType::None;
return !aDisplay.mShapeOutside.IsNone();
}
void Update(const nsStyleDisplay& aDisplay) {

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

@ -524,8 +524,7 @@ class nsFloatManager::ShapeInfo {
// Translate the current origin by the specified offsets.
virtual void Translate(nscoord aLineLeft, nscoord aBlockStart) = 0;
static LogicalRect ComputeShapeBoxRect(const StyleShapeSource& aShapeOutside,
nsIFrame* const aFrame,
static LogicalRect ComputeShapeBoxRect(StyleShapeBox, nsIFrame* const aFrame,
const LogicalRect& aMarginRect,
WritingMode aWM);
@ -2257,6 +2256,7 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, nscoord aLineLeft,
mRect(ShapeInfo::ConvertToFloatLogical(aMarginRect, aWM, aContainerSize) +
nsPoint(aLineLeft, aBlockStart)) {
MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
using ShapeOutsideType = StyleFloatAreaShape::Tag;
if (IsEmpty()) {
// Per spec, a float area defined by a shape is clipped to the floats
@ -2269,27 +2269,23 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, nscoord aLineLeft,
}
const nsStyleDisplay* styleDisplay = mFrame->StyleDisplay();
const StyleShapeSource& shapeOutside = styleDisplay->mShapeOutside;
const auto& shapeOutside = styleDisplay->mShapeOutside;
nscoord shapeMargin = (shapeOutside.GetType() == StyleShapeSourceType::None)
nscoord shapeMargin = shapeOutside.IsNone()
? 0
: nsLayoutUtils::ResolveToLength<true>(
styleDisplay->mShapeMargin,
LogicalSize(aWM, aContainerSize).ISize(aWM));
switch (shapeOutside.GetType()) {
case StyleShapeSourceType::None:
switch (shapeOutside.tag) {
case ShapeOutsideType::None:
// No need to create shape info.
return;
case StyleShapeSourceType::Path:
MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have Path source type!");
return;
case StyleShapeSourceType::Image: {
case ShapeOutsideType::ImageOrUrl: {
float shapeImageThreshold = styleDisplay->mShapeImageThreshold;
mShapeInfo = ShapeInfo::CreateImageShape(
shapeOutside.ShapeImage(), shapeImageThreshold, shapeMargin, mFrame,
shapeOutside.AsImageOrUrl(), shapeImageThreshold, shapeMargin, mFrame,
aMarginRect, aWM, aContainerSize);
if (!mShapeInfo) {
// Image is not ready, or fails to load, etc.
@ -2299,23 +2295,28 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, nscoord aLineLeft,
break;
}
case StyleShapeSourceType::Box: {
case ShapeOutsideType::Path:
// FIXME(emilio): We shouldn't generate the enum then.
MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have Path source type!");
return;
case ShapeOutsideType::Box: {
// Initialize <shape-box>'s reference rect.
LogicalRect shapeBoxRect = ShapeInfo::ComputeShapeBoxRect(
shapeOutside, mFrame, aMarginRect, aWM);
shapeOutside.AsBox(), mFrame, aMarginRect, aWM);
mShapeInfo = ShapeInfo::CreateShapeBox(mFrame, shapeMargin, shapeBoxRect,
aWM, aContainerSize);
break;
}
case StyleShapeSourceType::Shape: {
const StyleBasicShape& basicShape = shapeOutside.BasicShape();
case ShapeOutsideType::Shape: {
const auto& shape = *shapeOutside.AsShape()._0;
// Initialize <shape-box>'s reference rect.
LogicalRect shapeBoxRect = ShapeInfo::ComputeShapeBoxRect(
shapeOutside, mFrame, aMarginRect, aWM);
mShapeInfo = ShapeInfo::CreateBasicShape(basicShape, shapeMargin, mFrame,
shapeBoxRect, aMarginRect, aWM,
aContainerSize);
shapeOutside.AsShape()._1, mFrame, aMarginRect, aWM);
mShapeInfo =
ShapeInfo::CreateBasicShape(shape, shapeMargin, mFrame, shapeBoxRect,
aMarginRect, aWM, aContainerSize);
break;
}
}
@ -2437,27 +2438,25 @@ bool nsFloatManager::FloatInfo::MayNarrowInBlockDirection(
/* static */
LogicalRect nsFloatManager::ShapeInfo::ComputeShapeBoxRect(
const StyleShapeSource& aShapeOutside, nsIFrame* const aFrame,
const LogicalRect& aMarginRect, WritingMode aWM) {
StyleShapeBox aBox, nsIFrame* const aFrame, const LogicalRect& aMarginRect,
WritingMode aWM) {
LogicalRect rect = aMarginRect;
switch (aShapeOutside.GetReferenceBox()) {
case StyleGeometryBox::ContentBox:
switch (aBox) {
case StyleShapeBox::ContentBox:
rect.Deflate(aWM, aFrame->GetLogicalUsedPadding(aWM));
[[fallthrough]];
case StyleGeometryBox::PaddingBox:
case StyleShapeBox::PaddingBox:
rect.Deflate(aWM, aFrame->GetLogicalUsedBorder(aWM));
[[fallthrough]];
case StyleGeometryBox::BorderBox:
case StyleShapeBox::BorderBox:
rect.Deflate(aWM, aFrame->GetLogicalUsedMargin(aWM));
break;
case StyleGeometryBox::MarginBox:
case StyleShapeBox::MarginBox:
// Do nothing. rect is already a margin rect.
break;
case StyleGeometryBox::NoBox:
default:
MOZ_ASSERT(aShapeOutside.GetType() != StyleShapeSourceType::Box,
"Box source type must have <shape-box> specified!");
MOZ_ASSERT_UNREACHABLE("Unknown shape box");
break;
}
@ -2673,7 +2672,7 @@ nsFloatManager::ShapeInfo::CreateImageShape(const StyleImage& aShapeImage,
WritingMode aWM,
const nsSize& aContainerSize) {
MOZ_ASSERT(
&aShapeImage == &aFrame->StyleDisplay()->mShapeOutside.ShapeImage(),
&aShapeImage == &aFrame->StyleDisplay()->mShapeOutside.AsImageOrUrl(),
"aFrame should be the frame that we got aShapeImage from");
nsImageRenderer imageRenderer(aFrame, &aShapeImage,

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

@ -1324,13 +1324,19 @@ void nsFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
}
}
imgIRequest* oldShapeImage =
aOldComputedStyle
? aOldComputedStyle->StyleDisplay()->mShapeOutside.GetShapeImageData()
: nullptr;
imgIRequest* newShapeImage =
StyleDisplay()->mShapeOutside.GetShapeImageData();
auto GetShapeImageRequest = [](const ComputedStyle* aStyle) -> imgIRequest* {
if (!aStyle) {
return nullptr;
}
auto& shape = aStyle->StyleDisplay()->mShapeOutside;
if (!shape.IsImageOrUrl()) {
return nullptr;
}
return shape.AsImageOrUrl().GetImageRequest();
};
imgIRequest* oldShapeImage = GetShapeImageRequest(aOldComputedStyle);
imgIRequest* newShapeImage = GetShapeImageRequest(Style());
if (oldShapeImage != newShapeImage) {
if (oldShapeImage && HasImageRequest()) {
loader->DisassociateRequestFromFrame(oldShapeImage, this);
@ -2016,16 +2022,30 @@ bool nsIFrame::GetBoxBorderRadii(nscoord aRadii[8], nsMargin aOffset,
}
bool nsIFrame::GetShapeBoxBorderRadii(nscoord aRadii[8]) const {
switch (StyleDisplay()->mShapeOutside.GetReferenceBox()) {
case StyleGeometryBox::NoBox:
using Tag = StyleFloatAreaShape::Tag;
auto& shapeOutside = StyleDisplay()->mShapeOutside;
auto box = StyleShapeBox::MarginBox;
switch (shapeOutside.tag) {
case Tag::Path:
case Tag::ImageOrUrl:
case Tag::None:
return false;
case StyleGeometryBox::ContentBox:
case Tag::Box:
box = shapeOutside.AsBox();
break;
case Tag::Shape:
box = shapeOutside.AsShape()._1;
break;
}
switch (box) {
case StyleShapeBox::ContentBox:
return GetContentBoxBorderRadii(aRadii);
case StyleGeometryBox::PaddingBox:
case StyleShapeBox::PaddingBox:
return GetPaddingBoxBorderRadii(aRadii);
case StyleGeometryBox::BorderBox:
case StyleShapeBox::BorderBox:
return GetBorderRadii(aRadii);
case StyleGeometryBox::MarginBox:
case StyleShapeBox::MarginBox:
return GetMarginBoxBorderRadii(aRadii);
default:
MOZ_ASSERT_UNREACHABLE("Unexpected box value");

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

@ -9956,11 +9956,11 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
}
const auto& clipPath = style->mClipPath;
const auto& shape = clipPath.BasicShape();
const auto& shape = *clipPath.AsShape()._0;
auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
const nsRect refBox =
nsLayoutUtils::ComputeGeometryBox(frame, clipPath.GetReferenceBox());
nsLayoutUtils::ComputeGeometryBox(frame, clipPath.AsShape()._1);
AutoTArray<wr::ComplexClipRegion, 1> clipRegions;

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

@ -1263,29 +1263,6 @@ PropertyValuePair* Gecko_AppendPropertyValuePair(
return aProperties->AppendElement(PropertyValuePair{aProperty});
}
void Gecko_CopyShapeSourceFrom(StyleShapeSource* aDst,
const StyleShapeSource* aSrc) {
MOZ_ASSERT(aDst);
MOZ_ASSERT(aSrc);
*aDst = *aSrc;
}
void Gecko_DestroyShapeSource(StyleShapeSource* aShape) {
aShape->~StyleShapeSource();
}
void Gecko_NewShapeImage(StyleShapeSource* aShape) {
aShape->SetShapeImage(MakeUnique<StyleImage>(StyleImage::None()));
}
void Gecko_SetToSVGPath(StyleShapeSource* aShape,
StyleForgottenArcSlicePtr<StylePathCommand> aCommands,
StyleFillRule aFill) {
MOZ_ASSERT(aShape);
aShape->SetPath(MakeUnique<StyleSVGPath>(aCommands, aFill));
}
void Gecko_nsStyleSVG_SetDashArrayLength(nsStyleSVG* aSvg, uint32_t aLen) {
aSvg->mStrokeDasharray.Clear();
aSvg->mStrokeDasharray.SetLength(aLen);

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

@ -441,18 +441,6 @@ mozilla::Keyframe* Gecko_GetOrCreateFinalKeyframe(
mozilla::PropertyValuePair* Gecko_AppendPropertyValuePair(
nsTArray<mozilla::PropertyValuePair>*, nsCSSPropertyID aProperty);
void Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* dst,
const mozilla::StyleShapeSource* src);
void Gecko_DestroyShapeSource(mozilla::StyleShapeSource* shape);
void Gecko_NewShapeImage(mozilla::StyleShapeSource* shape);
void Gecko_SetToSVGPath(
mozilla::StyleShapeSource* shape,
mozilla::StyleForgottenArcSlicePtr<mozilla::StylePathCommand>,
mozilla::StyleFillRule);
void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);

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

@ -565,6 +565,8 @@ cbindgen-types = [
{ gecko = "StyleJustifyContent", servo = "values::computed::align::JustifyContent" },
{ gecko = "StyleComputedValueFlags", servo = "computed_value_flags::ComputedValueFlags" },
{ gecko = "StyleImage", servo = "values::computed::Image" },
{ gecko = "StyleClippingShape", servo = "values::computed::basic_shape::ClippingShape" },
{ gecko = "StyleFloatAreaShape", servo = "values::computed::basic_shape::FloatAreaShape" },
]
mapped-generic-types = [

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

@ -633,14 +633,17 @@ static void AddImageURL(const StyleImage& aImage,
}
}
static void AddImageURL(const StyleShapeSource& aShapeSource,
static void AddImageURL(const StyleFloatAreaShape& aShapeOutside,
nsTArray<nsCString>& aURLs) {
switch (aShapeSource.GetType()) {
case StyleShapeSourceType::Image:
AddImageURL(aShapeSource.ShapeImage(), aURLs);
break;
default:
break;
if (aShapeOutside.IsImageOrUrl()) {
AddImageURL(aShapeOutside.AsImageOrUrl(), aURLs);
}
}
static void AddImageURL(const StyleClippingShape& aClipPath,
nsTArray<nsCString>& aURLs) {
if (aClipPath.IsImageOrUrl()) {
AddImageURL(aClipPath.AsImageOrUrl(), aURLs);
}
}

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

@ -956,149 +956,6 @@ nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const {
return hint;
}
// --------------------
// StyleShapeSource
StyleShapeSource::StyleShapeSource() : mBasicShape() {}
StyleShapeSource::StyleShapeSource(const StyleShapeSource& aSource) {
DoCopy(aSource);
}
StyleShapeSource::~StyleShapeSource() { DoDestroy(); }
StyleShapeSource& StyleShapeSource::operator=(const StyleShapeSource& aOther) {
if (this != &aOther) {
DoCopy(aOther);
}
return *this;
}
bool StyleShapeSource::operator==(const StyleShapeSource& aOther) const {
if (mType != aOther.mType) {
return false;
}
switch (mType) {
case StyleShapeSourceType::None:
return true;
case StyleShapeSourceType::Image:
return *mShapeImage == *aOther.mShapeImage;
case StyleShapeSourceType::Shape:
return *mBasicShape == *aOther.mBasicShape &&
mReferenceBox == aOther.mReferenceBox;
case StyleShapeSourceType::Box:
return mReferenceBox == aOther.mReferenceBox;
case StyleShapeSourceType::Path:
return *mSVGPath == *aOther.mSVGPath;
}
MOZ_ASSERT_UNREACHABLE("Unexpected shape source type!");
return true;
}
void StyleShapeSource::SetShapeImage(UniquePtr<StyleImage> aShapeImage) {
MOZ_ASSERT(aShapeImage);
DoDestroy();
new (&mShapeImage) UniquePtr<StyleImage>(std::move(aShapeImage));
mType = StyleShapeSourceType::Image;
}
imgIRequest* StyleShapeSource::GetShapeImageData() const {
if (mType != StyleShapeSourceType::Image) {
return nullptr;
}
return mShapeImage->GetImageRequest();
}
void StyleShapeSource::SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
StyleGeometryBox aReferenceBox) {
MOZ_ASSERT(aBasicShape);
DoDestroy();
new (&mBasicShape) UniquePtr<StyleBasicShape>(std::move(aBasicShape));
mReferenceBox = aReferenceBox;
mType = StyleShapeSourceType::Shape;
}
void StyleShapeSource::SetPath(UniquePtr<StyleSVGPath> aPath) {
MOZ_ASSERT(aPath);
DoDestroy();
new (&mSVGPath) UniquePtr<StyleSVGPath>(std::move(aPath));
mType = StyleShapeSourceType::Path;
}
void StyleShapeSource::TriggerImageLoads(
Document& aDocument, const StyleShapeSource* aOldShapeSource) {
if (GetType() != StyleShapeSourceType::Image) {
return;
}
auto* oldShapeImage = (aOldShapeSource && aOldShapeSource->GetType() ==
StyleShapeSourceType::Image)
? &aOldShapeSource->ShapeImage()
: nullptr;
mShapeImage->ResolveImage(aDocument, oldShapeImage);
}
void StyleShapeSource::SetReferenceBox(StyleGeometryBox aReferenceBox) {
DoDestroy();
mReferenceBox = aReferenceBox;
mType = StyleShapeSourceType::Box;
}
void StyleShapeSource::DoCopy(const StyleShapeSource& aOther) {
switch (aOther.mType) {
case StyleShapeSourceType::None:
mReferenceBox = StyleGeometryBox::NoBox;
mType = StyleShapeSourceType::None;
break;
case StyleShapeSourceType::Image:
SetShapeImage(MakeUnique<StyleImage>(aOther.ShapeImage()));
break;
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());
break;
case StyleShapeSourceType::Path:
SetPath(MakeUnique<StyleSVGPath>(aOther.Path()));
break;
}
}
void StyleShapeSource::DoDestroy() {
switch (mType) {
case StyleShapeSourceType::Shape:
mBasicShape.~UniquePtr<StyleBasicShape>();
break;
case StyleShapeSourceType::Image:
mShapeImage.~UniquePtr<StyleImage>();
break;
case StyleShapeSourceType::Path:
mSVGPath.~UniquePtr<StyleSVGPath>();
break;
case StyleShapeSourceType::None:
case StyleShapeSourceType::Box:
// Not a union type, so do nothing.
break;
}
mType = StyleShapeSourceType::None;
}
// --------------------
// nsStyleSVGReset
//
@ -1111,6 +968,7 @@ nsStyleSVGReset::nsStyleSVGReset(const Document& aDocument)
mRy(NonNegativeLengthPercentageOrAuto::Auto()),
mR(NonNegativeLengthPercentage::Zero()),
mMask(nsStyleImageLayers::LayerType::Mask),
mClipPath(StyleClippingShape::None()),
mStopColor(StyleColor::Black()),
mFloodColor(StyleColor::Black()),
mLightingColor(StyleColor::White()),
@ -2417,7 +2275,8 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
mPerspectiveOrigin(Position::FromPercentage(0.5f)),
mVerticalAlign(
StyleVerticalAlign::Keyword(StyleVerticalAlignKeyword::Baseline)),
mShapeMargin(LengthPercentage::Zero()) {
mShapeMargin(LengthPercentage::Zero()),
mShapeOutside(StyleFloatAreaShape::None()) {
MOZ_COUNT_CTOR(nsStyleDisplay);
mTransitions[0].SetInitialValues();
@ -2493,8 +2352,15 @@ void nsStyleDisplay::TriggerImageLoads(Document& aDocument,
const nsStyleDisplay* aOldStyle) {
MOZ_ASSERT(NS_IsMainThread());
mShapeOutside.TriggerImageLoads(
aDocument, aOldStyle ? &aOldStyle->mShapeOutside : nullptr);
if (mShapeOutside.IsImageOrUrl()) {
auto* old = aOldStyle && aOldStyle->mShapeOutside.IsImageOrUrl()
? &aOldStyle->mShapeOutside.AsImageOrUrl()
: nullptr;
// Const-cast is ugly but legit, we could avoid it by generating mut-casts
// with cbindgen.
const_cast<StyleImage&>(mShapeOutside.AsImageOrUrl())
.ResolveImage(aDocument, old);
}
}
template <typename TransformLike>

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

@ -1130,104 +1130,6 @@ struct StyleAnimation {
float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
};
struct StyleSVGPath final {
StyleSVGPath(StyleForgottenArcSlicePtr<StylePathCommand> aPath,
StyleFillRule aFill)
: mPath(aPath), mFillRule(aFill) {}
Span<const StylePathCommand> Path() const { return mPath.AsSpan(); }
StyleFillRule FillRule() const { return mFillRule; }
bool operator==(const StyleSVGPath& aOther) const {
return mPath == aOther.mPath && mFillRule == aOther.mFillRule;
}
bool operator!=(const StyleSVGPath& aOther) const {
return !(*this == aOther);
}
private:
StyleArcSlice<StylePathCommand> mPath;
StyleFillRule mFillRule = StyleFillRule::Nonzero;
};
struct StyleShapeSource final {
StyleShapeSource();
StyleShapeSource(const StyleShapeSource& aSource);
~StyleShapeSource();
StyleShapeSource& operator=(const StyleShapeSource& aOther);
bool operator==(const StyleShapeSource& aOther) const;
bool operator!=(const StyleShapeSource& aOther) const {
return !(*this == aOther);
}
StyleShapeSourceType GetType() const { return mType; }
const StyleImage& ShapeImage() const {
MOZ_ASSERT(mType == StyleShapeSourceType::Image,
"Wrong shape source type!");
MOZ_ASSERT(mShapeImage);
return *mShapeImage;
}
// Iff we have "shape-outside:<image>" with an image URI (not a gradient),
// this method returns the corresponding imgIRequest*. Else, returns
// null.
imgIRequest* GetShapeImageData() const;
void SetShapeImage(UniquePtr<StyleImage> aShapeImage);
const StyleBasicShape& BasicShape() const {
MOZ_ASSERT(mType == StyleShapeSourceType::Shape,
"Wrong shape source type!");
MOZ_ASSERT(mBasicShape);
return *mBasicShape;
}
void SetBasicShape(UniquePtr<mozilla::StyleBasicShape> aBasicShape,
StyleGeometryBox aReferenceBox);
StyleGeometryBox GetReferenceBox() const {
MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
mType == StyleShapeSourceType::Shape,
"Wrong shape source type!");
return mReferenceBox;
}
void SetReferenceBox(StyleGeometryBox aReferenceBox);
const StyleSVGPath& Path() const {
MOZ_ASSERT(mType == StyleShapeSourceType::Path, "Wrong shape source type!");
MOZ_ASSERT(mSVGPath);
return *mSVGPath;
}
void SetPath(UniquePtr<StyleSVGPath> aPath);
void TriggerImageLoads(mozilla::dom::Document&,
const StyleShapeSource* aOldShapeSource);
private:
void* operator new(size_t) = delete;
void DoCopy(const StyleShapeSource& aOther);
void DoDestroy();
union {
UniquePtr<StyleBasicShape> mBasicShape;
UniquePtr<StyleImage> mShapeImage;
UniquePtr<StyleSVGPath> mSVGPath;
// TODO: Bug 1480665, implement ray() function.
};
StyleShapeSourceType mType = StyleShapeSourceType::None;
StyleGeometryBox mReferenceBox = StyleGeometryBox::NoBox;
};
} // namespace mozilla
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
@ -1371,7 +1273,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
// The margin around a shape-outside: <image>.
mozilla::NonNegativeLengthPercentage mShapeMargin;
mozilla::StyleShapeSource mShapeOutside;
mozilla::StyleFloatAreaShape mShapeOutside;
bool HasAppearance() const {
return mAppearance != mozilla::StyleAppearance::None;
@ -1944,9 +1846,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset {
nsChangeHint CalcDifference(const nsStyleSVGReset& aNewData) const;
bool HasClipPath() const {
return mClipPath.GetType() != mozilla::StyleShapeSourceType::None;
}
bool HasClipPath() const { return !mClipPath.IsNone(); }
bool HasMask() const;
@ -1964,7 +1864,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset {
mozilla::NonNegativeLengthPercentage mR;
nsStyleImageLayers mMask;
mozilla::StyleShapeSource mClipPath;
mozilla::StyleClippingShape mClipPath;
mozilla::StyleColor mStopColor;
mozilla::StyleColor mFloodColor;
mozilla::StyleColor mLightingColor;

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

@ -1261,14 +1261,12 @@ static nsSVGPaintingProperty* GetOrCreateClipPathObserver(
"Require first continuation");
const nsStyleSVGReset* svgStyleReset = aClippedFrame->StyleSVGReset();
if (svgStyleReset->mClipPath.GetType() != StyleShapeSourceType::Image) {
if (!svgStyleReset->mClipPath.IsImageOrUrl()) {
return nullptr;
}
const auto* url =
svgStyleReset->mClipPath.ShapeImage().GetImageRequestURLValue();
MOZ_ASSERT(url, "Clip-path only supports url() images");
const auto& url = svgStyleReset->mClipPath.AsImageOrUrl();
RefPtr<URLAndReferrerInfo> pathURI =
ResolveURLUsingLocalRef(aClippedFrame, *url);
ResolveURLUsingLocalRef(aClippedFrame, url);
return GetPaintingProperty(pathURI, aClippedFrame, ClipPathProperty());
}

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

@ -28,14 +28,10 @@ using namespace mozilla::gfx;
void nsCSSClipPathInstance::ApplyBasicShapeOrPathClip(
gfxContext& aContext, nsIFrame* aFrame, const gfxMatrix& aTransform) {
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
#ifdef DEBUG
StyleShapeSourceType type = clipPathStyle.GetType();
MOZ_ASSERT(type == StyleShapeSourceType::Shape ||
type == StyleShapeSourceType::Box ||
type == StyleShapeSourceType::Path,
MOZ_ASSERT(clipPathStyle.IsShape() || clipPathStyle.IsBox() ||
clipPathStyle.IsPath(),
"This is used with basic-shape, geometry-box, and path() only");
#endif
nsCSSClipPathInstance instance(aFrame, clipPathStyle);
aContext.NewPath();
@ -52,11 +48,10 @@ void nsCSSClipPathInstance::ApplyBasicShapeOrPathClip(
bool nsCSSClipPathInstance::HitTestBasicShapeOrPathClip(
nsIFrame* aFrame, const gfxPoint& aPoint) {
auto& clipPathStyle = aFrame->StyleSVGReset()->mClipPath;
StyleShapeSourceType type = clipPathStyle.GetType();
MOZ_ASSERT(type != StyleShapeSourceType::None, "unexpected none value");
MOZ_ASSERT(!clipPathStyle.IsNone(), "unexpected none value");
// In the future nsCSSClipPathInstance may handle <clipPath> references as
// well. For the time being return early.
if (type == StyleShapeSourceType::Image) {
if (clipPathStyle.IsImageOrUrl()) {
return false;
}
@ -73,10 +68,9 @@ bool nsCSSClipPathInstance::HitTestBasicShapeOrPathClip(
/* static */
Maybe<Rect> nsCSSClipPathInstance::GetBoundingRectForBasicShapeOrPathClip(
nsIFrame* aFrame, const StyleShapeSource& aClipPathStyle) {
MOZ_ASSERT(aClipPathStyle.GetType() == StyleShapeSourceType::Shape ||
aClipPathStyle.GetType() == StyleShapeSourceType::Box ||
aClipPathStyle.GetType() == StyleShapeSourceType::Path);
nsIFrame* aFrame, const StyleClippingShape& aClipPathStyle) {
MOZ_ASSERT(aClipPathStyle.IsShape() || aClipPathStyle.IsBox() ||
aClipPathStyle.IsPath());
nsCSSClipPathInstance instance(aFrame, aClipPathStyle);
@ -89,15 +83,20 @@ Maybe<Rect> nsCSSClipPathInstance::GetBoundingRectForBasicShapeOrPathClip(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPath(
DrawTarget* aDrawTarget, const gfxMatrix& aTransform) {
if (mClipPathStyle.GetType() == StyleShapeSourceType::Path) {
if (mClipPathStyle.IsPath()) {
return CreateClipPathPath(aDrawTarget);
}
nscoord appUnitsPerDevPixel =
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
nsRect r = nsLayoutUtils::ComputeGeometryBox(
mTargetFrame, mClipPathStyle.GetReferenceBox());
nsRect r;
if (mClipPathStyle.IsBox()) {
r = nsLayoutUtils::ComputeGeometryBox(mTargetFrame, mClipPathStyle.AsBox());
} else {
r = nsLayoutUtils::ComputeGeometryBox(mTargetFrame,
mClipPathStyle.AsShape()._1);
}
gfxRect rr(r.x, r.y, r.width, r.height);
rr.Scale(1.0 / AppUnitsPerCSSPixel());
@ -107,17 +106,17 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPath(
r = nsRect(int(rr.x), int(rr.y), int(rr.width), int(rr.height));
if (mClipPathStyle.GetType() == StyleShapeSourceType::Box) {
if (mClipPathStyle.IsBox()) {
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
AppendRectToPath(builder, NSRectToRect(r, appUnitsPerDevPixel), true);
return builder->Finish();
}
MOZ_ASSERT(mClipPathStyle.GetType() == StyleShapeSourceType::Shape);
MOZ_ASSERT(mClipPathStyle.IsShape());
r = ToAppUnits(r.ToNearestPixels(appUnitsPerDevPixel), appUnitsPerDevPixel);
const auto& basicShape = mClipPathStyle.BasicShape();
const auto& basicShape = *mClipPathStyle.AsShape()._0;
switch (basicShape.tag) {
case StyleBasicShape::Tag::Circle:
return CreateClipPathCircle(aDrawTarget, r);
@ -138,7 +137,7 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPath(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathCircle(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& basicShape = mClipPathStyle.BasicShape();
const auto& basicShape = *mClipPathStyle.AsShape()._0;
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -155,7 +154,7 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathCircle(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathEllipse(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& basicShape = mClipPathStyle.BasicShape();
const auto& basicShape = *mClipPathStyle.AsShape()._0;
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -173,7 +172,7 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathEllipse(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathPolygon(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& basicShape = mClipPathStyle.BasicShape();
const auto& basicShape = *mClipPathStyle.AsShape()._0;
auto fillRule = basicShape.AsPolygon().fill == StyleFillRule::Nonzero
? FillRule::FILL_WINDING
: FillRule::FILL_EVEN_ODD;
@ -198,7 +197,7 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathPolygon(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathInset(
DrawTarget* aDrawTarget, const nsRect& aRefBox) {
const auto& basicShape = mClipPathStyle.BasicShape();
const auto& basicShape = *mClipPathStyle.AsShape()._0;
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
@ -224,13 +223,13 @@ already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathInset(
already_AddRefed<Path> nsCSSClipPathInstance::CreateClipPathPath(
DrawTarget* aDrawTarget) {
const StyleSVGPath& path = mClipPathStyle.Path();
const auto& path = mClipPathStyle.AsPath();
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(
path.FillRule() == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
: FillRule::FILL_EVEN_ODD);
path.fill == StyleFillRule::Nonzero ? FillRule::FILL_WINDING
: FillRule::FILL_EVEN_ODD);
float scale = float(AppUnitsPerCSSPixel()) /
mTargetFrame->PresContext()->AppUnitsPerDevPixel();
return SVGPathData::BuildPath(path.Path(), builder, StyleStrokeLinecap::Butt,
0.0, scale);
return SVGPathData::BuildPath(path.path._0.AsSpan(), builder,
StyleStrokeLinecap::Butt, 0.0, scale);
}

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

@ -18,7 +18,7 @@ class gfxContext;
namespace mozilla {
class nsCSSClipPathInstance {
class MOZ_STACK_CLASS nsCSSClipPathInstance {
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Path Path;
typedef mozilla::gfx::Rect Rect;
@ -31,11 +31,11 @@ class nsCSSClipPathInstance {
const gfxPoint& aPoint);
static Maybe<Rect> GetBoundingRectForBasicShapeOrPathClip(
nsIFrame* aFrame, const StyleShapeSource& aClipPathStyle);
nsIFrame* aFrame, const StyleClippingShape& aClipPathStyle);
private:
explicit nsCSSClipPathInstance(nsIFrame* aFrame,
const StyleShapeSource& aClipPathStyle)
const StyleClippingShape& aClipPathStyle)
: mTargetFrame(aFrame), mClipPathStyle(aClipPathStyle) {}
already_AddRefed<Path> CreateClipPath(DrawTarget* aDrawTarget,
@ -59,7 +59,7 @@ class nsCSSClipPathInstance {
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
StyleShapeSource mClipPathStyle;
const StyleClippingShape& mClipPathStyle;
};
} // namespace mozilla

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

@ -183,12 +183,11 @@ bool nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(
}
const auto& clipPath = style->mClipPath;
if (clipPath.GetType() != StyleShapeSourceType::Shape) {
if (!clipPath.IsShape()) {
return false;
}
const auto& shape = clipPath.BasicShape();
return !shape.IsPolygon();
return !clipPath.AsShape()._0->IsPolygon();
}
nsPoint nsSVGIntegrationUtils::GetOffsetToBoundingBox(nsIFrame* aFrame) {

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

@ -429,6 +429,8 @@ float nsSVGUtils::ComputeOpacity(nsIFrame* aFrame, bool aHandleOpacity) {
void nsSVGUtils::DetermineMaskUsage(nsIFrame* aFrame, bool aHandleOpacity,
MaskUsage& aUsage) {
using ClipPathType = StyleClippingShape::Tag;
aUsage.opacity = ComputeOpacity(aFrame, aHandleOpacity);
nsIFrame* firstFrame =
@ -444,11 +446,10 @@ void nsSVGUtils::DetermineMaskUsage(nsIFrame* aFrame, bool aHandleOpacity,
nsSVGClipPathFrame* clipPathFrame;
// XXX check return value?
SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
MOZ_ASSERT(!clipPathFrame ||
svgReset->mClipPath.GetType() == StyleShapeSourceType::Image);
MOZ_ASSERT(!clipPathFrame || svgReset->mClipPath.IsImageOrUrl());
switch (svgReset->mClipPath.GetType()) {
case StyleShapeSourceType::Image:
switch (svgReset->mClipPath.tag) {
case ClipPathType::ImageOrUrl:
if (clipPathFrame) {
if (clipPathFrame->IsTrivial()) {
aUsage.shouldApplyClipPath = true;
@ -457,12 +458,12 @@ void nsSVGUtils::DetermineMaskUsage(nsIFrame* aFrame, bool aHandleOpacity,
}
}
break;
case StyleShapeSourceType::Shape:
case StyleShapeSourceType::Box:
case StyleShapeSourceType::Path:
case ClipPathType::Shape:
case ClipPathType::Box:
case ClipPathType::Path:
aUsage.shouldApplyBasicShapeOrPath = true;
break;
case StyleShapeSourceType::None:
case ClipPathType::None:
MOZ_ASSERT(!aUsage.shouldGenerateClipMaskLayer &&
!aUsage.shouldApplyClipPath &&
!aUsage.shouldApplyBasicShapeOrPath);

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

@ -15,159 +15,6 @@ use crate::stylesheets::RulesMutateError;
use crate::values::computed::transform::Matrix3D;
use crate::values::computed::TextAlign;
pub mod basic_shape {
//! Conversions from and to CSS shape representations.
use crate::gecko_bindings::structs::{
StyleGeometryBox, StyleShapeSource, StyleShapeSourceType,
};
use crate::values::computed::basic_shape::{BasicShape, ClippingShape, FloatAreaShape};
use crate::values::computed::motion::OffsetPath;
use crate::values::generics::basic_shape::{ShapeGeometryBox, Path, ShapeBox, ShapeSource};
use crate::values::specified::SVGPathData;
impl StyleShapeSource {
/// Convert StyleShapeSource to ShapeSource except URL and Image
/// types.
fn to_shape_source<ReferenceBox, ImageOrUrl>(
&self,
) -> Option<ShapeSource<BasicShape, ReferenceBox, ImageOrUrl>>
where
ReferenceBox: From<StyleGeometryBox> + Default + PartialEq,
{
match self.mType {
StyleShapeSourceType::None => Some(ShapeSource::None),
StyleShapeSourceType::Box => Some(ShapeSource::Box(self.mReferenceBox.into())),
StyleShapeSourceType::Shape => {
let other_shape = unsafe { &*self.__bindgen_anon_1.mBasicShape.as_ref().mPtr };
let shape = Box::new(other_shape.clone());
let reference_box = self.mReferenceBox.into();
Some(ShapeSource::Shape(shape, reference_box))
},
StyleShapeSourceType::Image => None,
StyleShapeSourceType::Path => {
let path = self.to_svg_path().expect("expect an SVGPathData");
let fill = unsafe { &*self.__bindgen_anon_1.mSVGPath.as_ref().mPtr }.mFillRule;
Some(ShapeSource::Path(Path { fill, path }))
},
}
}
/// Generate a SVGPathData from StyleShapeSource if possible.
fn to_svg_path(&self) -> Option<SVGPathData> {
match self.mType {
StyleShapeSourceType::Path => {
let gecko_path = unsafe { &*self.__bindgen_anon_1.mSVGPath.as_ref().mPtr };
Some(SVGPathData(gecko_path.mPath.clone()))
},
_ => None,
}
}
}
impl<'a> From<&'a StyleShapeSource> for ClippingShape {
fn from(other: &'a StyleShapeSource) -> Self {
match other.mType {
StyleShapeSourceType::Image => unsafe {
use crate::values::generics::image::Image as GenericImage;
let shape_image = &*other.__bindgen_anon_1.mShapeImage.as_ref().mPtr;
match *shape_image {
GenericImage::Url(ref url) => ShapeSource::ImageOrUrl(url.0.clone()),
_ => panic!("ClippingShape doesn't support non-url images"),
}
},
_ => other
.to_shape_source()
.expect("Couldn't convert to StyleSource!"),
}
}
}
impl<'a> From<&'a StyleShapeSource> for FloatAreaShape {
fn from(other: &'a StyleShapeSource) -> Self {
match other.mType {
StyleShapeSourceType::Image => unsafe {
let shape_image = &*other.__bindgen_anon_1.mShapeImage.as_ref().mPtr;
ShapeSource::ImageOrUrl(shape_image.clone())
},
_ => other
.to_shape_source()
.expect("Couldn't convert to StyleSource!"),
}
}
}
impl<'a> From<&'a StyleShapeSource> for OffsetPath {
fn from(other: &'a StyleShapeSource) -> Self {
use crate::values::generics::motion::GenericOffsetPath;
match other.mType {
StyleShapeSourceType::Path => GenericOffsetPath::Path(
other.to_svg_path().expect("Cannot convert to SVGPathData"),
),
StyleShapeSourceType::None => OffsetPath::none(),
StyleShapeSourceType::Shape |
StyleShapeSourceType::Box |
StyleShapeSourceType::Image => unreachable!("Unsupported offset-path type"),
}
}
}
impl From<ShapeBox> for StyleGeometryBox {
fn from(reference: ShapeBox) -> Self {
use crate::gecko_bindings::structs::StyleGeometryBox::*;
match reference {
ShapeBox::ContentBox => ContentBox,
ShapeBox::PaddingBox => PaddingBox,
ShapeBox::BorderBox => BorderBox,
ShapeBox::MarginBox => MarginBox,
}
}
}
impl From<ShapeGeometryBox> for StyleGeometryBox {
fn from(reference: ShapeGeometryBox) -> Self {
use crate::gecko_bindings::structs::StyleGeometryBox::*;
match reference {
ShapeGeometryBox::ShapeBox(shape_box) => From::from(shape_box),
ShapeGeometryBox::FillBox => FillBox,
ShapeGeometryBox::StrokeBox => StrokeBox,
ShapeGeometryBox::ViewBox => ViewBox,
ShapeGeometryBox::ElementDependent => NoBox,
}
}
}
impl From<StyleGeometryBox> for ShapeGeometryBox {
fn from(reference: StyleGeometryBox) -> Self {
use crate::gecko_bindings::structs::StyleGeometryBox::*;
match reference {
ContentBox => ShapeGeometryBox::ShapeBox(ShapeBox::ContentBox),
PaddingBox => ShapeGeometryBox::ShapeBox(ShapeBox::PaddingBox),
BorderBox => ShapeGeometryBox::ShapeBox(ShapeBox::BorderBox),
MarginBox => ShapeGeometryBox::ShapeBox(ShapeBox::MarginBox),
FillBox => ShapeGeometryBox::FillBox,
StrokeBox => ShapeGeometryBox::StrokeBox,
ViewBox => ShapeGeometryBox::ViewBox,
NoBox => ShapeGeometryBox::ElementDependent,
NoClip | Text | MozAlmostPadding => unreachable!(),
}
}
}
impl From<StyleGeometryBox> for ShapeBox {
fn from(reference: StyleGeometryBox) -> Self {
use crate::gecko_bindings::structs::StyleGeometryBox::*;
match reference {
ContentBox => ShapeBox::ContentBox,
PaddingBox => ShapeBox::PaddingBox,
BorderBox => ShapeBox::BorderBox,
MarginBox => ShapeBox::MarginBox,
_ => panic!("Unexpected StyleGeometryBox while converting to ShapeBox"),
}
}
}
}
impl From<RulesMutateError> for nsresult {
fn from(other: RulesMutateError) -> Self {
match other {

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

@ -41,7 +41,6 @@ use std::mem::{forget, MaybeUninit};
use std::{cmp, ops, ptr};
use crate::values::{self, CustomIdent, Either, KeyframesName, None_};
use crate::values::computed::{Percentage, TransitionProperty};
use crate::values::computed::url::ComputedImageUrl;
use crate::values::computed::BorderStyle;
use crate::values::computed::font::FontSize;
use crate::values::generics::column::ColumnCount;
@ -1433,7 +1432,7 @@ fn static_assert() {
animation-iteration-count animation-timing-function
clear transition-duration transition-delay
transition-timing-function transition-property
shape-outside -webkit-line-clamp""" %>
-webkit-line-clamp""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
#[inline]
pub fn set_display(&mut self, v: longhands::display::computed_value::T) {
@ -1693,8 +1692,6 @@ fn static_assert() {
${impl_animation_timing_function()}
<% impl_shape_source("shape_outside", "mShapeOutside") %>
#[allow(non_snake_case)]
pub fn set__webkit_line_clamp(&mut self, v: longhands::_webkit_line_clamp::computed_value::T) {
self.gecko.mLineClamp = match v {
@ -2202,84 +2199,8 @@ fn static_assert() {
}
</%self:impl_trait>
// Set SVGPathData to StyleShapeSource.
fn set_style_svg_path(
shape_source: &mut structs::mozilla::StyleShapeSource,
servo_path: values::specified::svg_path::SVGPathData,
fill: values::generics::basic_shape::FillRule,
) {
// Setup path.
unsafe {
bindings::Gecko_SetToSVGPath(
shape_source,
servo_path.0.forget(),
fill,
);
}
}
<%def name="impl_shape_source(ident, gecko_ffi_name)">
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use crate::values::generics::basic_shape::ShapeSource;
use crate::gecko_bindings::structs::StyleShapeSourceType;
let ref mut ${ident} = self.gecko.${gecko_ffi_name};
// clean up existing struct.
unsafe { bindings::Gecko_DestroyShapeSource(${ident}) };
${ident}.mType = StyleShapeSourceType::None;
match v {
ShapeSource::None => {} // don't change the type
ShapeSource::ImageOrUrl(image) => {
% if ident == "clip_path":
use crate::values::generics::image::Image;
let image = Image::Url(ComputedImageUrl(image));
% endif
unsafe {
bindings::Gecko_NewShapeImage(${ident});
let style_image = &mut *${ident}.__bindgen_anon_1.mShapeImage.as_mut().mPtr;
*style_image = image;
}
}
ShapeSource::Box(reference) => {
${ident}.mReferenceBox = reference.into();
${ident}.mType = StyleShapeSourceType::Box;
}
ShapeSource::Path(p) => set_style_svg_path(${ident}, p.path, p.fill),
ShapeSource::Shape(servo_shape, reference_box) => {
unsafe {
${ident}.__bindgen_anon_1.mBasicShape.as_mut().mPtr =
Box::into_raw(servo_shape);
}
${ident}.mReferenceBox = reference_box.into();
${ident}.mType = StyleShapeSourceType::Shape;
}
}
}
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
(&self.gecko.${gecko_ffi_name}).into()
}
pub fn copy_${ident}_from(&mut self, other: &Self) {
use crate::gecko_bindings::bindings::Gecko_CopyShapeSourceFrom;
unsafe {
Gecko_CopyShapeSourceFrom(&mut self.gecko.${gecko_ffi_name}, &other.gecko.${gecko_ffi_name});
}
}
pub fn reset_${ident}(&mut self, other: &Self) {
self.copy_${ident}_from(other)
}
</%def>
<% skip_svg_longhands = """
mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask-position-y mask-size mask-image
clip-path
"""
%>
<%self:impl_trait style_struct_name="SVG"
@ -2288,7 +2209,6 @@ clip-path
<% impl_common_image_layer_properties("mask") %>
<% impl_simple_image_array_property("mode", "mask", "mMask", "mMaskMode", "SVG") %>
<% impl_simple_image_array_property("composite", "mask", "mMask", "mComposite", "SVG") %>
<% impl_shape_source("clip_path", "mClipPath") %>
</%self:impl_trait>
<%self:impl_trait style_struct_name="InheritedSVG"

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

@ -205,6 +205,8 @@ include = [
"JustifyContent",
"TransformStyle",
"Image",
"ClippingShape",
"FloatAreaShape",
]
item_types = ["enums", "structs", "unions", "typedefs", "functions", "constants"]
renaming_overrides_prefixing = true