mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1074056 - Part 1 - Add support for interpolation hints to CSS gradients. r=dbaron
This commit is contained in:
parent
be6fb5965d
commit
85aa244222
@ -8804,12 +8804,15 @@ CSSParserImpl::ParseColorStop(nsCSSValueGradient* aGradient)
|
||||
{
|
||||
nsCSSValueGradientStop* stop = aGradient->mStops.AppendElement();
|
||||
if (!ParseVariant(stop->mColor, VARIANT_COLOR, nullptr)) {
|
||||
return false;
|
||||
stop->mIsInterpolationHint = true;
|
||||
}
|
||||
|
||||
// Stop positions do not have to fall between the starting-point and
|
||||
// ending-point, so we don't use ParseNonNegativeVariant.
|
||||
if (!ParseVariant(stop->mLocation, VARIANT_LP | VARIANT_CALC, nullptr)) {
|
||||
if (stop->mIsInterpolationHint) {
|
||||
return false;
|
||||
}
|
||||
stop->mLocation.SetNoneValue();
|
||||
}
|
||||
return true;
|
||||
@ -9157,6 +9160,20 @@ CSSParserImpl::ParseGradientColorStops(nsCSSValueGradient* aGradient,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if interpolation hints are in the correct location
|
||||
bool previousPointWasInterpolationHint = true;
|
||||
for (size_t x = 0; x < aGradient->mStops.Length(); x++) {
|
||||
bool isInterpolationHint = aGradient->mStops[x].mIsInterpolationHint;
|
||||
if (isInterpolationHint && previousPointWasInterpolationHint) {
|
||||
return false;
|
||||
}
|
||||
previousPointWasInterpolationHint = isInterpolationHint;
|
||||
}
|
||||
|
||||
if (previousPointWasInterpolationHint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aValue.SetGradientValue(aGradient);
|
||||
return true;
|
||||
}
|
||||
|
@ -1414,10 +1414,15 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
}
|
||||
|
||||
for (uint32_t i = 0 ;;) {
|
||||
bool isInterpolationHint = gradient->mStops[i].mIsInterpolationHint;
|
||||
if (!isInterpolationHint) {
|
||||
gradient->mStops[i].mColor.AppendToString(aProperty, aResult,
|
||||
aSerialization);
|
||||
}
|
||||
if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
|
||||
if (!isInterpolationHint) {
|
||||
aResult.Append(' ');
|
||||
}
|
||||
gradient->mStops[i].mLocation.AppendToString(aProperty, aResult,
|
||||
aSerialization);
|
||||
}
|
||||
@ -2351,14 +2356,16 @@ css::ImageValue::~ImageValue()
|
||||
|
||||
nsCSSValueGradientStop::nsCSSValueGradientStop()
|
||||
: mLocation(eCSSUnit_None),
|
||||
mColor(eCSSUnit_Null)
|
||||
mColor(eCSSUnit_Null),
|
||||
mIsInterpolationHint(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSValueGradientStop);
|
||||
}
|
||||
|
||||
nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
|
||||
: mLocation(aOther.mLocation),
|
||||
mColor(aOther.mColor)
|
||||
mColor(aOther.mColor),
|
||||
mIsInterpolationHint(aOther.mIsInterpolationHint)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSValueGradientStop);
|
||||
}
|
||||
|
@ -1341,11 +1341,15 @@ public:
|
||||
|
||||
nsCSSValue mLocation;
|
||||
nsCSSValue mColor;
|
||||
// If mIsInterpolationHint is true, there is no color, just
|
||||
// a location.
|
||||
bool mIsInterpolationHint;
|
||||
|
||||
bool operator==(const nsCSSValueGradientStop& aOther) const
|
||||
{
|
||||
return (mLocation == aOther.mLocation &&
|
||||
mColor == aOther.mColor);
|
||||
mIsInterpolationHint == aOther.mIsInterpolationHint &&
|
||||
(mIsInterpolationHint || mColor == aOther.mColor));
|
||||
}
|
||||
|
||||
bool operator!=(const nsCSSValueGradientStop& aOther) const
|
||||
|
@ -1928,13 +1928,19 @@ nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient,
|
||||
if (needSep) {
|
||||
aString.AppendLiteral(", ");
|
||||
}
|
||||
SetToRGBAColor(tmpVal, aGradient->mStops[i].mColor);
|
||||
|
||||
const auto& stop = aGradient->mStops[i];
|
||||
if (!stop.mIsInterpolationHint) {
|
||||
SetToRGBAColor(tmpVal, stop.mColor);
|
||||
tmpVal->GetCssText(tokenString);
|
||||
aString.Append(tokenString);
|
||||
}
|
||||
|
||||
if (aGradient->mStops[i].mLocation.GetUnit() != eStyleUnit_None) {
|
||||
if (stop.mLocation.GetUnit() != eStyleUnit_None) {
|
||||
if (!stop.mIsInterpolationHint) {
|
||||
aString.Append(' ');
|
||||
AppendCSSGradientLength(aGradient->mStops[i].mLocation, tmpVal, aString);
|
||||
}
|
||||
AppendCSSGradientLength(stop.mLocation, tmpVal, aString);
|
||||
}
|
||||
needSep = true;
|
||||
}
|
||||
|
@ -1107,12 +1107,20 @@ static void SetGradient(const nsCSSValue& aValue, nsPresContext* aPresContext,
|
||||
NS_NOTREACHED("unexpected unit for gradient stop location");
|
||||
}
|
||||
|
||||
stop.mIsInterpolationHint = valueStop.mIsInterpolationHint;
|
||||
|
||||
// inherit is not a valid color for stops, so we pass in a dummy
|
||||
// parent color
|
||||
NS_ASSERTION(valueStop.mColor.GetUnit() != eCSSUnit_Inherit,
|
||||
"inherit is not a valid color for gradient stops");
|
||||
if (!valueStop.mIsInterpolationHint) {
|
||||
SetColor(valueStop.mColor, NS_RGB(0, 0, 0), aPresContext,
|
||||
aContext, stop.mColor, aCanStoreInRuleTree);
|
||||
} else {
|
||||
// Always initialize to the same color so we don't need to worry
|
||||
// about comparisons.
|
||||
stop.mColor = NS_RGB(0, 0, 0);
|
||||
}
|
||||
|
||||
aResult.mStops.AppendElement(stop);
|
||||
}
|
||||
|
@ -1766,8 +1766,11 @@ nsStyleGradient::operator==(const nsStyleGradient& aOther) const
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
if (mStops[i].mLocation != aOther.mStops[i].mLocation ||
|
||||
mStops[i].mColor != aOther.mStops[i].mColor)
|
||||
const auto& stop1 = mStops[i];
|
||||
const auto& stop2 = aOther.mStops[i];
|
||||
if (stop1.mLocation != stop2.mLocation ||
|
||||
stop1.mIsInterpolationHint != stop2.mIsInterpolationHint ||
|
||||
(!stop1.mIsInterpolationHint && stop1.mColor != stop2.mColor))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,11 @@ public:
|
||||
struct nsStyleGradientStop {
|
||||
nsStyleCoord mLocation; // percent, coord, calc, none
|
||||
nscolor mColor;
|
||||
bool mIsInterpolationHint;
|
||||
|
||||
// Use ==/!= on nsStyleGradient instead of on the gradient stop.
|
||||
bool operator==(const nsStyleGradientStop&) const MOZ_DELETE;
|
||||
bool operator!=(const nsStyleGradientStop&) const MOZ_DELETE;
|
||||
};
|
||||
|
||||
class nsStyleGradient MOZ_FINAL {
|
||||
|
@ -86,6 +86,18 @@ var validGradientAndElementValues = [
|
||||
"linear-gradient(1turn, red, blue)",
|
||||
"linear-gradient(.414rad, red, blue)",
|
||||
|
||||
"linear-gradient(.414rad, red, 50%, blue)",
|
||||
"linear-gradient(.414rad, red, 0%, blue)",
|
||||
"linear-gradient(.414rad, red, 100%, blue)",
|
||||
|
||||
"linear-gradient(.414rad, red 50%, 50%, blue 50%)",
|
||||
"linear-gradient(.414rad, red 50%, 20%, blue 50%)",
|
||||
"linear-gradient(.414rad, red 50%, 30%, blue 10%)",
|
||||
"linear-gradient(to right bottom, red, 20%, green 50%, 65%, blue)",
|
||||
"linear-gradient(to right bottom, red, 20%, green 10%, blue)",
|
||||
"linear-gradient(to right bottom, red, 50%, green 50%, 50%, blue)",
|
||||
"linear-gradient(to right bottom, red, 0%, green 50%, 100%, blue)",
|
||||
|
||||
"-moz-linear-gradient(red, blue)",
|
||||
"-moz-linear-gradient(red, yellow, blue)",
|
||||
"-moz-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
|
||||
@ -504,6 +516,13 @@ var invalidGradientAndElementValues = [
|
||||
"linear-gradient(1turn 20px, red, blue)",
|
||||
"linear-gradient(.414rad bottom, red, blue)",
|
||||
|
||||
"linear-gradient(to top, 0%, blue)",
|
||||
"linear-gradient(to top, red, 100%)",
|
||||
"linear-gradient(to top, red, 45%, 56%, blue)",
|
||||
"linear-gradient(to top, red,, blue)",
|
||||
"linear-gradient(to top, red, green 35%, 15%, 54%, blue)",
|
||||
|
||||
|
||||
"radial-gradient(top left 45deg, red, blue)",
|
||||
"radial-gradient(20% bottom -300deg, red, blue)",
|
||||
"radial-gradient(center 20% 1.95929rad, red, blue)",
|
||||
|
Loading…
Reference in New Issue
Block a user