Bug 1347409 part 2 - serialise fill and stroke fallback properly r=cam

This commit is contained in:
Robert Longson 2017-05-02 22:12:59 +01:00
Родитель 506a15c672
Коммит 0c1b6c1fcc
11 изменённых файлов: 148 добавлений и 61 удалений

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

@ -1542,7 +1542,7 @@ void
Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* aPaint, ServoBundledURI aURI)
{
RefPtr<css::URLValue> url = aURI.IntoCssUrl();
aPaint->SetPaintServer(url.get(), NS_RGB(0, 0, 0));
aPaint->SetPaintServer(url.get());
}
void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint)

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

@ -4192,6 +4192,16 @@ StyleClipBasicShapeToCSSArray(const StyleShapeSource& aClipPath,
return true;
}
static void
SetFallbackValue(nsCSSValuePair* aPair, const nsStyleSVGPaint& aPaint)
{
if (aPaint.GetFallbackType() == eStyleSVGFallbackType_Color) {
aPair->mYValue.SetColorValue(aPaint.GetFallbackColor());
} else {
aPair->mYValue.SetNoneValue();
}
}
bool
StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
nsStyleContext* aStyleContext,
@ -4709,22 +4719,33 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
NS_WARNING("Null paint server");
return false;
}
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetURLValue(url);
pair->mYValue.SetColorValue(paint.GetFallbackColor());
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
if (paint.GetFallbackType() != eStyleSVGFallbackType_NotSet) {
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetURLValue(url);
SetFallbackValue(pair, paint);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
} else {
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(url);
aComputedValue.SetAndAdoptCSSValueValue(
result.release(), eUnit_URL);
}
return true;
}
case eStyleSVGPaintType_ContextFill:
case eStyleSVGPaintType_ContextStroke: {
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetIntValue(paint.Type() == eStyleSVGPaintType_ContextFill ?
NS_COLOR_CONTEXT_FILL : NS_COLOR_CONTEXT_STROKE,
eCSSUnit_Enumerated);
pair->mYValue.SetColorValue(paint.GetFallbackColor());
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
int32_t value = paint.Type() == eStyleSVGPaintType_ContextFill ?
NS_COLOR_CONTEXT_FILL : NS_COLOR_CONTEXT_STROKE;
if (paint.GetFallbackType() != eStyleSVGFallbackType_NotSet) {
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetIntValue(value, eCSSUnit_Enumerated);
SetFallbackValue(pair, paint);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
} else {
aComputedValue.SetIntValue(value, eUnit_Enumerated);
}
return true;
}
default:

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

@ -17302,6 +17302,7 @@ CSSParserImpl::ParsePaint(nsCSSPropertyID aPropID)
return false;
}
bool hasFallback = false;
bool canHaveFallback = x.GetUnit() == eCSSUnit_URL ||
x.GetUnit() == eCSSUnit_Enumerated;
if (canHaveFallback) {
@ -17309,17 +17310,16 @@ CSSParserImpl::ParsePaint(nsCSSPropertyID aPropID)
ParseVariant(y, VARIANT_COLOR | VARIANT_NONE, nullptr);
if (result == CSSParseResult::Error) {
return false;
} else if (result == CSSParseResult::NotFound) {
y.SetNoneValue();
}
hasFallback = (result != CSSParseResult::NotFound);
}
if (!canHaveFallback) {
AppendValue(aPropID, x);
} else {
if (hasFallback) {
nsCSSValue val;
val.SetPairValue(x, y);
AppendValue(aPropID, val);
} else {
AppendValue(aPropID, x);
}
return true;
}

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

@ -5768,18 +5768,25 @@ nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord& aHeight)
return true;
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::GetFallbackValue(const nsStyleSVGPaint* aPaint)
{
RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
if (aPaint->GetFallbackType() == eStyleSVGFallbackType_Color) {
SetToRGBAColor(fallback, aPaint->GetFallbackColor());
} else {
fallback->SetIdent(eCSSKeyword_none);
}
return fallback.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::GetSVGPaintFor(bool aFill)
{
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
const nsStyleSVG* svg = StyleSVG();
const nsStyleSVGPaint* paint = nullptr;
if (aFill)
paint = &svg->mFill;
else
paint = &svg->mStroke;
const nsStyleSVGPaint* paint = aFill ? &svg->mFill : &svg->mStroke;
nsAutoString paintString;
@ -5791,23 +5798,29 @@ nsComputedDOMStyle::GetSVGPaintFor(bool aFill)
SetToRGBAColor(val, paint->GetColor());
break;
case eStyleSVGPaintType_Server: {
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
SetValueToURLValue(paint->GetPaintServer(), val);
SetToRGBAColor(fallback, paint->GetFallbackColor());
valueList->AppendCSSValue(val.forget());
valueList->AppendCSSValue(fallback.forget());
return valueList.forget();
if (paint->GetFallbackType() != eStyleSVGFallbackType_NotSet) {
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
RefPtr<CSSValue> fallback = GetFallbackValue(paint);
valueList->AppendCSSValue(val.forget());
valueList->AppendCSSValue(fallback.forget());
return valueList.forget();
}
break;
}
case eStyleSVGPaintType_ContextFill:
val->SetIdent(eCSSKeyword_context_fill);
// XXXheycam context-fill and context-stroke can have fallback colors,
// so they should be serialized here too
break;
case eStyleSVGPaintType_ContextStroke:
val->SetIdent(eCSSKeyword_context_stroke);
case eStyleSVGPaintType_ContextStroke: {
val->SetIdent(paint->Type() == eStyleSVGPaintType_ContextFill ?
eCSSKeyword_context_fill : eCSSKeyword_context_stroke);
if (paint->GetFallbackType() != eStyleSVGFallbackType_NotSet) {
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
RefPtr<CSSValue> fallback = GetFallbackValue(paint);
valueList->AppendCSSValue(val.forget());
valueList->AppendCSSValue(fallback.forget());
return valueList.forget();
}
break;
}
}
return val.forget();

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

@ -198,6 +198,8 @@ private:
already_AddRefed<CSSValue> GetMarginWidthFor(mozilla::Side aSide);
already_AddRefed<CSSValue> GetFallbackValue(const nsStyleSVGPaint* aPaint);
already_AddRefed<CSSValue> GetSVGPaintFor(bool aFill);
// Appends all aLineNames (may be empty) space-separated to aResult.

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

@ -9357,32 +9357,51 @@ SetSVGPaint(const nsCSSValue& aValue, const nsStyleSVGPaint& parentPaint,
} else {
aResult.SetColor(NS_RGB(0, 0, 0));
}
} else if (aValue.GetUnit() == eCSSUnit_URL) {
aResult.SetPaintServer(aValue.GetURLStructValue());
} else if (aValue.GetUnit() == eCSSUnit_Enumerated) {
switch (aValue.GetIntValue()) {
case NS_COLOR_CONTEXT_FILL:
aResult.SetContextValue(eStyleSVGPaintType_ContextFill);
break;
case NS_COLOR_CONTEXT_STROKE:
aResult.SetContextValue(eStyleSVGPaintType_ContextStroke);
break;
default:
NS_NOTREACHED("unknown keyword as paint server value");
}
} else if (SetColor(aValue, NS_RGB(0, 0, 0), aPresContext, aContext,
color, aConditions)) {
aResult.SetColor(color);
} else if (aValue.GetUnit() == eCSSUnit_Pair) {
const nsCSSValuePair& pair = aValue.GetPairValue();
nsStyleSVGFallbackType fallbackType;
nscolor fallback;
if (pair.mYValue.GetUnit() == eCSSUnit_None) {
fallbackType = eStyleSVGFallbackType_None;
fallback = NS_RGBA(0, 0, 0, 0);
} else {
MOZ_ASSERT(pair.mYValue.GetUnit() != eCSSUnit_Inherit,
"cannot inherit fallback colour");
fallbackType = eStyleSVGFallbackType_Color;
SetColor(pair.mYValue, NS_RGB(0, 0, 0), aPresContext, aContext,
fallback, aConditions);
}
if (pair.mXValue.GetUnit() == eCSSUnit_URL) {
aResult.SetPaintServer(pair.mXValue.GetURLStructValue(), fallback);
aResult.SetPaintServer(pair.mXValue.GetURLStructValue(),
fallbackType, fallback);
} else if (pair.mXValue.GetUnit() == eCSSUnit_Enumerated) {
switch (pair.mXValue.GetIntValue()) {
case NS_COLOR_CONTEXT_FILL:
aResult.SetContextValue(eStyleSVGPaintType_ContextFill, fallback);
aResult.SetContextValue(eStyleSVGPaintType_ContextFill,
fallbackType, fallback);
break;
case NS_COLOR_CONTEXT_STROKE:
aResult.SetContextValue(eStyleSVGPaintType_ContextStroke, fallback);
aResult.SetContextValue(eStyleSVGPaintType_ContextStroke,
fallbackType, fallback);
break;
default:
NS_NOTREACHED("unknown keyword as paint server value");

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

@ -1320,11 +1320,14 @@ nsStyleSVGPaint::Assign(const nsStyleSVGPaint& aOther)
break;
case eStyleSVGPaintType_Server:
SetPaintServer(aOther.mPaint.mPaintServer,
aOther.mFallbackType,
aOther.mFallbackColor);
break;
case eStyleSVGPaintType_ContextFill:
case eStyleSVGPaintType_ContextStroke:
SetContextValue(aOther.mType, aOther.mFallbackColor);
SetContextValue(aOther.mType,
aOther.mFallbackType,
aOther.mFallbackColor);
break;
}
}
@ -1338,12 +1341,14 @@ nsStyleSVGPaint::SetNone()
void
nsStyleSVGPaint::SetContextValue(nsStyleSVGPaintType aType,
nsStyleSVGFallbackType aFallbackType,
nscolor aFallbackColor)
{
MOZ_ASSERT(aType == eStyleSVGPaintType_ContextFill ||
aType == eStyleSVGPaintType_ContextStroke);
Reset();
mType = aType;
mFallbackType = aFallbackType;
mFallbackColor = aFallbackColor;
}
@ -1357,6 +1362,7 @@ nsStyleSVGPaint::SetColor(nscolor aColor)
void
nsStyleSVGPaint::SetPaintServer(css::URLValue* aPaintServer,
nsStyleSVGFallbackType aFallbackType,
nscolor aFallbackColor)
{
MOZ_ASSERT(aPaintServer);
@ -1364,6 +1370,7 @@ nsStyleSVGPaint::SetPaintServer(css::URLValue* aPaintServer,
mType = eStyleSVGPaintType_Server;
mPaint.mPaintServer = aPaintServer;
mPaint.mPaintServer->AddRef();
mFallbackType = aFallbackType;
mFallbackColor = aFallbackColor;
}
@ -1378,10 +1385,12 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
case eStyleSVGPaintType_Server:
return DefinitelyEqualURIs(mPaint.mPaintServer,
aOther.mPaint.mPaintServer) &&
mFallbackType == aOther.mFallbackType &&
mFallbackColor == aOther.mFallbackColor;
case eStyleSVGPaintType_ContextFill:
case eStyleSVGPaintType_ContextStroke:
return mFallbackColor == aOther.mFallbackColor;
return mFallbackType == aOther.mFallbackType &&
mFallbackColor == aOther.mFallbackColor;
default:
MOZ_ASSERT(mType == eStyleSVGPaintType_None,
"Unexpected SVG paint type");

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

@ -3410,9 +3410,18 @@ public:
void SetNone();
void SetColor(nscolor aColor);
void SetPaintServer(mozilla::css::URLValue* aPaintServer,
nsStyleSVGFallbackType aFallbackType,
nscolor aFallbackColor);
void SetPaintServer(mozilla::css::URLValue* aPaintServer) {
SetPaintServer(aPaintServer, eStyleSVGFallbackType_NotSet,
NS_RGB(0, 0, 0));
}
void SetContextValue(nsStyleSVGPaintType aType,
nsStyleSVGFallbackType aFallbackType,
nscolor aFallbackColor);
void SetContextValue(nsStyleSVGPaintType aType) {
SetContextValue(aType, eStyleSVGFallbackType_NotSet, NS_RGB(0, 0, 0));
}
nscolor GetColor() const {
MOZ_ASSERT(mType == eStyleSVGPaintType_Color);

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

@ -74,8 +74,6 @@ to mochitest command.
* test_animations_event_order.html [2]
* test_computed_style.html `gradient`: -moz- and -webkit-prefixed gradient values [35]
* ... `mask`: mask-image isn't set properly bug 1341667 [10]
* ... `fill`: svg paint should distinguish whether there is fallback bug 1347409 [2]
* ... `stroke`: svg paint should distinguish whether there is fallback bug 1347409 [2]
* character not properly escaped servo/servo#15947
* test_parse_url.html [1]
* test_bug829816.html [8]

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

@ -470,22 +470,22 @@ var noframe_container = document.getElementById("content");
var nonLocalURL = "url(\"foo.svg#foo\")";
var resolvedNonLocalURL = "url(\"" + docPath + "foo.svg#foo\")";
var testStyles = {
"mask" : "",
"markerStart" : "",
"markerMid" : "",
"markerEnd" : "",
"clipPath" : "",
"filter" : "",
"fill" : " rgba(0, 0, 0, 0)",
"stroke" : " rgba(0, 0, 0, 0)",
};
var testStyles = [
"mask",
"markerStart",
"markerMid",
"markerEnd",
"clipPath",
"filter",
"fill",
"stroke",
];
for (var prop in testStyles) {
for (var prop of testStyles) {
p.style[prop] = localURL;
is(cs[prop], localURL + testStyles[prop], "computed value of " + prop);
is(cs[prop], localURL, "computed value of " + prop);
p.style[prop] = nonLocalURL;
is(cs[prop], resolvedNonLocalURL + testStyles[prop], "computed value of " + prop);
is(cs[prop], resolvedNonLocalURL, "computed value of " + prop);
}
p.remove();

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

@ -1453,10 +1453,18 @@ nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
{
const nsStyleSVGPaint &paint = aStyleContext->StyleSVG()->*aFillOrStroke;
nsStyleContext *styleIfVisited = aStyleContext->GetStyleIfVisited();
bool isServer = paint.Type() == eStyleSVGPaintType_Server ||
paint.Type() == eStyleSVGPaintType_ContextFill ||
paint.Type() == eStyleSVGPaintType_ContextStroke;
nscolor color = isServer ? paint.GetFallbackColor() : paint.GetColor();
nscolor color;
switch (paint.Type()) {
case eStyleSVGPaintType_Server:
case eStyleSVGPaintType_ContextFill:
case eStyleSVGPaintType_ContextStroke:
color = paint.GetFallbackType() == eStyleSVGFallbackType_Color ?
paint.GetFallbackColor() : NS_RGBA(0, 0, 0, 0);
break;
default:
color = paint.GetColor();
break;
}
if (styleIfVisited) {
const nsStyleSVGPaint &paintIfVisited =
styleIfVisited->StyleSVG()->*aFillOrStroke;
@ -1542,6 +1550,10 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
}
}
if (style->mFill.GetFallbackType() == eStyleSVGFallbackType_None) {
return DrawResult::SUCCESS;
}
// On failure, use the fallback colour in case we have an
// objectBoundingBox where the width or height of the object is zero.
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
@ -1618,6 +1630,10 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
}
}
if (style->mStroke.GetFallbackType() == eStyleSVGFallbackType_None) {
return DrawResult::SUCCESS;
}
// On failure, use the fallback colour in case we have an
// objectBoundingBox where the width or height of the object is zero.
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox