зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1217643 part 2: Represent parsed CSS -webkit-gradient(linear, ...) expressions internally as parsed versions of more modern syntax. r=heycam
This commit is contained in:
Родитель
8244546943
Коммит
c177fd8597
|
@ -5,14 +5,14 @@ default-preferences pref(layout.css.prefixes.webkit,true)
|
||||||
# Tests where we don't render a "-webkit-gradient" exactly correctly.
|
# Tests where we don't render a "-webkit-gradient" exactly correctly.
|
||||||
# (These just ensure that our approximate/do-something rendering does not
|
# (These just ensure that our approximate/do-something rendering does not
|
||||||
# change unexpectedly.)
|
# change unexpectedly.)
|
||||||
fails == webkit-gradient-approx-linear-1.html webkit-gradient-approx-linear-1-ref.html
|
fuzzy-if(cocoaWidget,3,3369) == webkit-gradient-approx-linear-1.html webkit-gradient-approx-linear-1-ref.html # bug 1225372
|
||||||
fails == webkit-gradient-approx-radial-1.html webkit-gradient-approx-radial-1-ref.html
|
fails == webkit-gradient-approx-radial-1.html webkit-gradient-approx-radial-1-ref.html
|
||||||
|
|
||||||
# Tests for -webkit-gradient(linear, ...)
|
# Tests for -webkit-gradient(linear, ...)
|
||||||
== webkit-gradient-linear-1a.html webkit-gradient-linear-1-ref.html
|
== webkit-gradient-linear-1a.html webkit-gradient-linear-1-ref.html
|
||||||
fails == webkit-gradient-linear-1b.html webkit-gradient-linear-1-ref.html
|
== webkit-gradient-linear-1b.html webkit-gradient-linear-1-ref.html
|
||||||
fails == webkit-gradient-linear-1c.html webkit-gradient-linear-1-ref.html
|
== webkit-gradient-linear-1c.html webkit-gradient-linear-1-ref.html
|
||||||
fails == webkit-gradient-linear-1d.html webkit-gradient-linear-1-ref.html
|
== webkit-gradient-linear-1d.html webkit-gradient-linear-1-ref.html
|
||||||
== webkit-gradient-linear-2.html webkit-gradient-linear-2-ref.html
|
== webkit-gradient-linear-2.html webkit-gradient-linear-2-ref.html
|
||||||
|
|
||||||
# Tests for -webkit-gradient(radial, ...)
|
# Tests for -webkit-gradient(radial, ...)
|
||||||
|
|
|
@ -10284,9 +10284,40 @@ CSSParserImpl::ParseWebkitGradientColorStops(nsCSSValueGradient* aGradient)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compares aStartCoord to aEndCoord, and returns true iff they share the same
|
||||||
|
// unit (both pixel, or both percent) and aStartCoord is larger.
|
||||||
|
static bool
|
||||||
|
IsWebkitGradientCoordLarger(const nsCSSValue& aStartCoord,
|
||||||
|
const nsCSSValue& aEndCoord)
|
||||||
|
{
|
||||||
|
if (aStartCoord.GetUnit() == eCSSUnit_Percent &&
|
||||||
|
aEndCoord.GetUnit() == eCSSUnit_Percent) {
|
||||||
|
return aStartCoord.GetPercentValue() > aEndCoord.GetPercentValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aStartCoord.GetUnit() == eCSSUnit_Pixel &&
|
||||||
|
aEndCoord.GetUnit() == eCSSUnit_Pixel) {
|
||||||
|
return aStartCoord.GetFloatValue() > aEndCoord.GetFloatValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can't compare them, since their units differ. Returning false suggests
|
||||||
|
// that aEndCoord is larger, which is probably a decent guess anyway.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Finalize our internal representation of a -webkit-gradient(linear, ...)
|
// Finalize our internal representation of a -webkit-gradient(linear, ...)
|
||||||
// expression, given the parsed points. (The parsed color stops
|
// expression, given the parsed points. (The parsed color stops
|
||||||
// should already be hanging off of the passed-in nsCSSValueGradient.)
|
// should already be hanging off of the passed-in nsCSSValueGradient.)
|
||||||
|
//
|
||||||
|
// Note: linear gradients progress along a line between two points. The
|
||||||
|
// -webkit-gradient(linear, ...) syntax lets the author precisely specify the
|
||||||
|
// starting and ending point point. However, our internal gradient structures
|
||||||
|
// only store one point, and the other point is implicitly its reflection
|
||||||
|
// across the painted area's center. (The legacy -moz-linear-gradient syntax
|
||||||
|
// also lets us store an angle.)
|
||||||
|
//
|
||||||
|
// In this function, we try to go from the two-point representation to an
|
||||||
|
// equivalent or approximately-equivalent one-point representation.
|
||||||
void
|
void
|
||||||
CSSParserImpl::FinalizeLinearWebkitGradient(nsCSSValueGradient* aGradient,
|
CSSParserImpl::FinalizeLinearWebkitGradient(nsCSSValueGradient* aGradient,
|
||||||
const nsCSSValuePair& aStartPoint,
|
const nsCSSValuePair& aStartPoint,
|
||||||
|
@ -10294,10 +10325,51 @@ CSSParserImpl::FinalizeLinearWebkitGradient(nsCSSValueGradient* aGradient,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!aGradient->mIsRadial, "passed-in gradient must be linear");
|
MOZ_ASSERT(!aGradient->mIsRadial, "passed-in gradient must be linear");
|
||||||
|
|
||||||
aGradient->mIsLegacySyntax = true; // (Needed in order to use non-% points)
|
// If the start & end points have the same Y-coordinate, then we can treat
|
||||||
aGradient->mBgPos = aStartPoint;
|
// this as a horizontal gradient progressing towards the center of the left
|
||||||
|
// or right side.
|
||||||
|
if (aStartPoint.mYValue == aEndPoint.mYValue) {
|
||||||
|
aGradient->mBgPos.mYValue.SetIntValue(NS_STYLE_BG_POSITION_CENTER,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
if (IsWebkitGradientCoordLarger(aStartPoint.mXValue, aEndPoint.mXValue)) {
|
||||||
|
aGradient->mBgPos.mXValue.SetIntValue(NS_STYLE_BG_POSITION_LEFT,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
} else {
|
||||||
|
aGradient->mBgPos.mXValue.SetIntValue(NS_STYLE_BG_POSITION_RIGHT,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// XXXdholbert Do further positioning/angling here.
|
// If the start & end points have the same X-coordinate, then we can treat
|
||||||
|
// this as a horizontal gradient progressing towards the center of the top
|
||||||
|
// or bottom side.
|
||||||
|
if (aStartPoint.mXValue == aEndPoint.mXValue) {
|
||||||
|
aGradient->mBgPos.mXValue.SetIntValue(NS_STYLE_BG_POSITION_CENTER,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
if (IsWebkitGradientCoordLarger(aStartPoint.mYValue, aEndPoint.mYValue)) {
|
||||||
|
aGradient->mBgPos.mYValue.SetIntValue(NS_STYLE_BG_POSITION_TOP,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
} else {
|
||||||
|
aGradient->mBgPos.mYValue.SetIntValue(NS_STYLE_BG_POSITION_BOTTOM,
|
||||||
|
eCSSUnit_Enumerated);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, the gradient is angled, which means we likely can't represent it
|
||||||
|
// exactly in |aGradient|, without doing analysis on the two points to
|
||||||
|
// extract an angle (which we might not be able to do depending on the units
|
||||||
|
// used). For now, we'll just do something really basic -- just use the
|
||||||
|
// first point as if it were the starting point in a legacy
|
||||||
|
// -moz-linear-gradient() expression. That way, the rendered gradient will
|
||||||
|
// progress from this first point, towards the center of the covered element,
|
||||||
|
// to a reflected end point on the far side. Note that we have to use
|
||||||
|
// mIsLegacySyntax=true for this to work, because standardized (non-legacy)
|
||||||
|
// gradients place some restrictions on the reference point [namely, that it
|
||||||
|
// use percent units & be on the border of the element].
|
||||||
|
aGradient->mIsLegacySyntax = true;
|
||||||
|
aGradient->mBgPos = aStartPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize our internal representation of a -webkit-gradient(radial, ...)
|
// Finalize our internal representation of a -webkit-gradient(radial, ...)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче