diff --git a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js index 6f023474e876..1202f27d85e9 100644 --- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js +++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js @@ -223,6 +223,7 @@ function treatAsSafeArgument(entry, varName, csuName) ["Gecko_DestroyShapeSource", "aShape", null], ["Gecko_StyleShapeSource_SetURLValue", "aShape", null], ["Gecko_NewBasicShape", "aShape", null], + ["Gecko_NewShapeImage", "aShape", null], ["Gecko_nsFont_InitSystem", "aDest", null], ["Gecko_nsFont_SetFontFeatureValuesLookup", "aFont", null], ["Gecko_nsFont_ResetFontFeatureValuesLookup", "aFont", null], diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index 5c84e51c837b..44ba8ef952bd 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -756,30 +756,38 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, const StyleShapeSource& shapeOutside = mFrame->StyleDisplay()->mShapeOutside; - if (shapeOutside.GetType() == StyleShapeSourceType::None) { - return; - } + switch (shapeOutside.GetType()) { + case StyleShapeSourceType::None: + // No need to create shape info. + return; - if (shapeOutside.GetType() == StyleShapeSourceType::URL) { - // Bug 1265343: Implement 'shape-image-threshold'. Early return - // here because shape-outside with url() value doesn't have a - // reference box, and GetReferenceBox() asserts that. - return; - } + case StyleShapeSourceType::URL: + MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have URL source type!"); + return; - // Initialize 's reference rect. - LogicalRect shapeBoxRect = - ShapeInfo::ComputeShapeBoxRect(shapeOutside, mFrame, aMarginRect, aWM); + case StyleShapeSourceType::Image: + // Bug 1265343: Implement 'shape-image-threshold' + // Bug 1404222: Support shape-outside: + return; - if (shapeOutside.GetType() == StyleShapeSourceType::Box) { - mShapeInfo = ShapeInfo::CreateShapeBox(mFrame, shapeBoxRect, aWM, - aContainerSize); - } else if (shapeOutside.GetType() == StyleShapeSourceType::Shape) { - const UniquePtr& basicShape = shapeOutside.GetBasicShape(); - mShapeInfo = ShapeInfo::CreateBasicShape(basicShape, shapeBoxRect, aWM, + case StyleShapeSourceType::Box: { + // Initialize 's reference rect. + LogicalRect shapeBoxRect = + ShapeInfo::ComputeShapeBoxRect(shapeOutside, mFrame, aMarginRect, aWM); + mShapeInfo = ShapeInfo::CreateShapeBox(mFrame, shapeBoxRect, aWM, aContainerSize); - } else { - MOZ_ASSERT_UNREACHABLE("Unknown StyleShapeSourceType!"); + break; + } + + case StyleShapeSourceType::Shape: { + const UniquePtr& basicShape = shapeOutside.GetBasicShape(); + // Initialize 's reference rect. + LogicalRect shapeBoxRect = + ShapeInfo::ComputeShapeBoxRect(shapeOutside, mFrame, aMarginRect, aWM); + mShapeInfo = ShapeInfo::CreateBasicShape(basicShape, shapeBoxRect, aWM, + aContainerSize); + break; + } } MOZ_ASSERT(mShapeInfo, diff --git a/layout/inspector/inDOMUtils.cpp b/layout/inspector/inDOMUtils.cpp index 4c80c2f04881..304574d0eae7 100644 --- a/layout/inspector/inDOMUtils.cpp +++ b/layout/inspector/inDOMUtils.cpp @@ -816,10 +816,13 @@ PropertySupportsVariant(nsCSSPropertyID aPropertyID, uint32_t aVariant) case eCSSProperty_content: case eCSSProperty_cursor: case eCSSProperty_clip_path: - case eCSSProperty_shape_outside: supported = VARIANT_URL; break; + case eCSSProperty_shape_outside: + supported = VARIANT_IMAGE; + break; + case eCSSProperty_fill: case eCSSProperty_stroke: supported = VARIANT_COLOR | VARIANT_URL; diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 2c59a7cbe1f3..5cb23de71284 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -2028,6 +2028,12 @@ Gecko_NewBasicShape(mozilla::StyleShapeSource* aShape, StyleGeometryBox::NoBox); } +void +Gecko_NewShapeImage(mozilla::StyleShapeSource* aShape) +{ + aShape->SetShapeImage(MakeUnique()); +} + void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len) { diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index dc3476a71233..c9eb1052eb64 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -519,6 +519,7 @@ void Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* dst, const mozilla::St 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, ServoBundledURI uri); void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len); diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp index d780e0c4301c..4a3ea7fc013c 100644 --- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -4245,6 +4245,9 @@ ExtractComputedValueFromShapeSource(const StyleShapeSource& aShapeSource, aComputedValue.SetCSSValueArrayValue(result, StyleAnimationValue::eUnit_Shape); + } else if (type == StyleShapeSourceType::Image) { + // XXX: Won't implement because Gecko style system will be removed. + return false; } else { MOZ_ASSERT(type == StyleShapeSourceType::None, "unknown type"); aComputedValue.SetNoneValue(); diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 8951edd2af8d..3924eceaeb3f 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -16445,8 +16445,16 @@ CSSParserImpl::ParseClipPath(nsCSSValue& aValue) bool CSSParserImpl::ParseShapeOutside(nsCSSValue& aValue) { - if (ParseSingleTokenVariant(aValue, VARIANT_HUO, nullptr)) { - // 'inherit', 'initial', 'unset', 'none', and url must be alone. + CSSParseResult result = + ParseVariant(aValue, VARIANT_IMAGE | VARIANT_INHERIT, nullptr); + + if (result == CSSParseResult::Error) { + return false; + } + + if (result == CSSParseResult::Ok) { + // 'inherit', 'initial', 'unset', 'none', and ( or + // ) must be alone. return true; } diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 2b14ef687426..2d33cd56b39b 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -3765,6 +3765,7 @@ CSS_PROP_DISPLAY( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_PARSER_FUNCTION | CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | + CSS_PROPERTY_START_IMAGE_LOADS | CSS_PROPERTY_STORES_CALC, "layout.css.shape-outside.enabled", 0, diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 68cec631bd6c..172ba2382554 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -6553,8 +6553,11 @@ nsComputedDOMStyle::GetShapeSource( val->SetIdent(eCSSKeyword_none); return val.forget(); } - default: - NS_NOTREACHED("unexpected type"); + case StyleShapeSourceType::Image: { + RefPtr val = new nsROCSSPrimitiveValue; + SetValueToStyleImage(*aShapeSource.GetShapeImage(), val); + return val.forget(); + } } return nullptr; } diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d190fd02962c..fe1e751a5eea 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -6434,9 +6434,14 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, conditions.SetUncacheable(); display->mShapeOutside = parentDisplay->mShapeOutside; break; - case eCSSUnit_URL: { + case eCSSUnit_Image: + case eCSSUnit_Function: + case eCSSUnit_Gradient: + case eCSSUnit_Element: { + auto shapeImage = MakeUnique(); + SetStyleImage(aContext, *shapeOutsideValue, *shapeImage, conditions); display->mShapeOutside = StyleShapeSource(); - display->mShapeOutside.SetURL(shapeOutsideValue->GetURLStructValue()); + display->mShapeOutside.SetShapeImage(Move(shapeImage)); break; } case eCSSUnit_Array: { diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 323f8c21bbbe..800fd1ed61e1 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -154,7 +154,8 @@ enum class StyleShapeRadius : uint8_t { // Shape source type enum class StyleShapeSourceType : uint8_t { None, - URL, + URL, // clip-path only + Image, // shape-outside only Shape, Box, }; diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 9008eed4bad9..363199b623c9 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1073,15 +1073,23 @@ StyleShapeSource::operator==(const StyleShapeSource& aOther) const return false; } - if (mType == StyleShapeSourceType::URL) { - return DefinitelyEqualURIs(GetURL(), aOther.GetURL()); - } else if (mType == StyleShapeSourceType::Shape) { - return *mBasicShape == *aOther.mBasicShape && - mReferenceBox == aOther.mReferenceBox; - } else if (mType == StyleShapeSourceType::Box) { - return mReferenceBox == aOther.mReferenceBox; + switch (mType) { + case StyleShapeSourceType::None: + return true; + + case StyleShapeSourceType::URL: + case StyleShapeSourceType::Image: + return *mShapeImage == *aOther.mShapeImage; + + case StyleShapeSourceType::Shape: + return *mBasicShape == *aOther.mBasicShape && + mReferenceBox == aOther.mReferenceBox; + + case StyleShapeSourceType::Box: + return mReferenceBox == aOther.mReferenceBox; } + MOZ_ASSERT_UNREACHABLE("Unexpected shape source type!"); return true; } @@ -1096,11 +1104,19 @@ StyleShapeSource::SetURL(css::URLValue* aValue) mType = StyleShapeSourceType::URL; } +void +StyleShapeSource::SetShapeImage(UniquePtr aShapeImage) +{ + MOZ_ASSERT(aShapeImage); + mShapeImage = Move(aShapeImage); + mType = StyleShapeSourceType::Image; +} + void StyleShapeSource::SetBasicShape(UniquePtr aBasicShape, StyleGeometryBox aReferenceBox) { - NS_ASSERTION(aBasicShape, "expected pointer"); + MOZ_ASSERT(aBasicShape); mBasicShape = Move(aBasicShape); mReferenceBox = aReferenceBox; mType = StyleShapeSourceType::Shape; @@ -1116,7 +1132,6 @@ StyleShapeSource::SetReferenceBox(StyleGeometryBox aReferenceBox) void StyleShapeSource::DoCopy(const StyleShapeSource& aOther) { - switch (aOther.mType) { case StyleShapeSourceType::None: mReferenceBox = StyleGeometryBox::NoBox; @@ -1127,6 +1142,10 @@ StyleShapeSource::DoCopy(const StyleShapeSource& aOther) SetURL(aOther.GetURL()); break; + case StyleShapeSourceType::Image: + SetShapeImage(MakeUnique(*aOther.GetShapeImage())); + break; + case StyleShapeSourceType::Shape: SetBasicShape(MakeUnique(*aOther.GetBasicShape()), aOther.GetReferenceBox()); @@ -3697,6 +3716,20 @@ nsStyleDisplay::~nsStyleDisplay() MOZ_COUNT_DTOR(nsStyleDisplay); } +void +nsStyleDisplay::FinishStyle(nsPresContext* aPresContext) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aPresContext->StyleSet()->IsServo()); + + if (mShapeOutside.GetType() == StyleShapeSourceType::Image) { + const UniquePtr& shapeImage = mShapeOutside.GetShapeImage(); + if (shapeImage) { + shapeImage->ResolveImage(aPresContext); + } + } +} + nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const { diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 995d4f3db9ea..f41e0b470fec 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -2474,6 +2474,14 @@ struct StyleShapeSource final void SetURL(css::URLValue* aValue); + const UniquePtr& GetShapeImage() const + { + MOZ_ASSERT(mType == StyleShapeSourceType::Image, "Wrong shape source type!"); + return mShapeImage; + } + + void SetShapeImage(UniquePtr aShapeImage); + const UniquePtr& GetBasicShape() const { MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!"); @@ -2514,8 +2522,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay nsStyleDisplay(const nsStyleDisplay& aOther); ~nsStyleDisplay(); - void FinishStyle(nsPresContext* aPresContext) {} - const static bool kHasFinishStyle = false; + void FinishStyle(nsPresContext* aPresContext); + const static bool kHasFinishStyle = true; void* operator new(size_t sz, nsStyleDisplay* aSelf) { return aSelf; } void* operator new(size_t sz, nsPresContext* aContext) {