Bug 1418224 Part 3 - Add shape-outside: <image> support to style system. r=heycam

Some Gecko style system files are modified to prevent assertions and
crashing, and to keep test failures on stylo disabled builds to minimum.

MozReview-Commit-ID: GuxAeCTz0xx

--HG--
extra : rebase_source : 2342085d13a50535836be46d75a731641d0fc49e
This commit is contained in:
Ting-Yu Lin 2017-11-17 16:34:37 +08:00
Родитель 56d6b694a2
Коммит 80fee1a237
13 изменённых файлов: 120 добавлений и 39 удалений

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

@ -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],

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

@ -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 <shape-box>'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: <image>
return;
if (shapeOutside.GetType() == StyleShapeSourceType::Box) {
mShapeInfo = ShapeInfo::CreateShapeBox(mFrame, shapeBoxRect, aWM,
aContainerSize);
} else if (shapeOutside.GetType() == StyleShapeSourceType::Shape) {
const UniquePtr<StyleBasicShape>& basicShape = shapeOutside.GetBasicShape();
mShapeInfo = ShapeInfo::CreateBasicShape(basicShape, shapeBoxRect, aWM,
case StyleShapeSourceType::Box: {
// Initialize <shape-box>'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<StyleBasicShape>& basicShape = shapeOutside.GetBasicShape();
// Initialize <shape-box>'s reference rect.
LogicalRect shapeBoxRect =
ShapeInfo::ComputeShapeBoxRect(shapeOutside, mFrame, aMarginRect, aWM);
mShapeInfo = ShapeInfo::CreateBasicShape(basicShape, shapeBoxRect, aWM,
aContainerSize);
break;
}
}
MOZ_ASSERT(mShapeInfo,

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

@ -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;

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

@ -2028,6 +2028,12 @@ Gecko_NewBasicShape(mozilla::StyleShapeSource* aShape,
StyleGeometryBox::NoBox);
}
void
Gecko_NewShapeImage(mozilla::StyleShapeSource* aShape)
{
aShape->SetShapeImage(MakeUnique<nsStyleImage>());
}
void
Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len)
{

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

@ -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);

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

@ -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();

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

@ -16445,8 +16445,16 @@ CSSParserImpl::ParseClipPath(nsCSSValue& aValue)
bool
CSSParserImpl::ParseShapeOutside(nsCSSValue& aValue)
{
if (ParseSingleTokenVariant(aValue, VARIANT_HUO, nullptr)) {
// 'inherit', 'initial', 'unset', 'none', and <image> 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 <image> (<url> or
// <gradient>) must be alone.
return true;
}

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

@ -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,

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

@ -6553,8 +6553,11 @@ nsComputedDOMStyle::GetShapeSource(
val->SetIdent(eCSSKeyword_none);
return val.forget();
}
default:
NS_NOTREACHED("unexpected type");
case StyleShapeSourceType::Image: {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
SetValueToStyleImage(*aShapeSource.GetShapeImage(), val);
return val.forget();
}
}
return nullptr;
}

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

@ -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<nsStyleImage>();
SetStyleImage(aContext, *shapeOutsideValue, *shapeImage, conditions);
display->mShapeOutside = StyleShapeSource();
display->mShapeOutside.SetURL(shapeOutsideValue->GetURLStructValue());
display->mShapeOutside.SetShapeImage(Move(shapeImage));
break;
}
case eCSSUnit_Array: {

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

@ -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,
};

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

@ -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<nsStyleImage> aShapeImage)
{
MOZ_ASSERT(aShapeImage);
mShapeImage = Move(aShapeImage);
mType = StyleShapeSourceType::Image;
}
void
StyleShapeSource::SetBasicShape(UniquePtr<StyleBasicShape> 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<nsStyleImage>(*aOther.GetShapeImage()));
break;
case StyleShapeSourceType::Shape:
SetBasicShape(MakeUnique<StyleBasicShape>(*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<nsStyleImage>& shapeImage = mShapeOutside.GetShapeImage();
if (shapeImage) {
shapeImage->ResolveImage(aPresContext);
}
}
}
nsChangeHint
nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
{

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

@ -2474,6 +2474,14 @@ struct StyleShapeSource final
void SetURL(css::URLValue* aValue);
const UniquePtr<nsStyleImage>& GetShapeImage() const
{
MOZ_ASSERT(mType == StyleShapeSourceType::Image, "Wrong shape source type!");
return mShapeImage;
}
void SetShapeImage(UniquePtr<nsStyleImage> aShapeImage);
const UniquePtr<StyleBasicShape>& 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) {