Commit a1f25a6c authored by fmalita's avatar fmalita Committed by Commit bot

Remove Gradient point/radius setters

These are only called from CSSGradientValue to adjust the points/radii
immediately after Gradient instantiation.

Refactor CSSGradientValue to perform the adjustment before constructing
the Gradient object.  No functional changes.

BUG=614368
R=schenney@chromium.org,fs@opera.com

Review-Url: https://codereview.chromium.org/2754703003
Cr-Commit-Position: refs/heads/master@{#457498}
parent 38c96095
......@@ -124,6 +124,26 @@ struct GradientStop {
GradientStop() : offset(0), specified(false) {}
};
struct CSSGradientValue::GradientDesc {
STACK_ALLOCATED();
GradientDesc(const FloatPoint& p0,
const FloatPoint& p1,
GradientSpreadMethod spreadMethod)
: p0(p0), p1(p1), spreadMethod(spreadMethod) {}
GradientDesc(const FloatPoint& p0,
const FloatPoint& p1,
float r0,
float r1,
GradientSpreadMethod spreadMethod)
: p0(p0), p1(p1), r0(r0), r1(r1), spreadMethod(spreadMethod) {}
Vector<Gradient::ColorStop> stops;
FloatPoint p0, p1;
float r0 = 0, r1 = 0;
GradientSpreadMethod spreadMethod = SpreadMethodPad;
};
static void replaceColorHintsWithColorStops(
Vector<GradientStop>& stops,
const HeapVector<CSSGradientColorStop, 2>& cssGradientStops) {
......@@ -223,7 +243,7 @@ static Color resolveStopColor(const CSSValue& stopColor,
stopColor, object.resolveColor(CSSPropertyColor));
}
void CSSGradientValue::addDeprecatedStops(Gradient* gradient,
void CSSGradientValue::addDeprecatedStops(GradientDesc& desc,
const LayoutObject& object) {
ASSERT(m_gradientType == CSSDeprecatedLinearGradient ||
m_gradientType == CSSDeprecatedRadialGradient);
......@@ -241,19 +261,19 @@ void CSSGradientValue::addDeprecatedStops(Gradient* gradient,
else
offset = stop.m_position->getFloatValue();
gradient->addColorStop(offset, resolveStopColor(*stop.m_color, object));
desc.stops.emplace_back(offset, resolveStopColor(*stop.m_color, object));
}
}
static bool requiresStopsNormalization(const Vector<GradientStop>& stops,
const Gradient* gradient) {
CSSGradientValue::GradientDesc& desc) {
// We need at least two stops to normalize
if (stops.size() < 2)
return false;
// Repeating gradients are implemented using a normalized stop offset range
// with the point/radius pairs aligned on the interval endpoints.
if (gradient->spreadMethod() == SpreadMethodRepeat)
if (desc.spreadMethod == SpreadMethodRepeat)
return true;
// Degenerate stops
......@@ -266,7 +286,7 @@ static bool requiresStopsNormalization(const Vector<GradientStop>& stops,
// Redistribute the stops such that they fully cover [0 , 1] and add them to the
// gradient.
static bool normalizeAndAddStops(const Vector<GradientStop>& stops,
Gradient* gradient) {
CSSGradientValue::GradientDesc& desc) {
ASSERT(stops.size() > 1);
const float firstOffset = stops.front().offset;
......@@ -281,9 +301,9 @@ static bool normalizeAndAddStops(const Vector<GradientStop>& stops,
// image with the color of the last color-stop in the rule.
// For non-repeating gradients, both the first color and the last color can
// be significant (padding on both sides of the offset).
if (gradient->spreadMethod() != SpreadMethodRepeat)
gradient->addColorStop(clampedOffset, stops.front().color);
gradient->addColorStop(clampedOffset, stops.back().color);
if (desc.spreadMethod != SpreadMethodRepeat)
desc.stops.emplace_back(clampedOffset, stops.front().color);
desc.stops.emplace_back(clampedOffset, stops.back().color);
return false;
}
......@@ -298,7 +318,7 @@ static bool normalizeAndAddStops(const Vector<GradientStop>& stops,
ASSERT(i == 0 ||
normalizedOffset >= (stops[i - 1].offset - firstOffset) / span);
gradient->addColorStop(normalizedOffset, stops[i].color);
desc.stops.emplace_back(normalizedOffset, stops[i].color);
}
return true;
......@@ -332,31 +352,31 @@ static void clampNegativeOffsets(Vector<GradientStop>& stops) {
}
// Update the linear gradient points to align with the given offset range.
static void adjustGradientPointsForOffsetRange(Gradient* gradient,
float firstOffset,
float lastOffset) {
ASSERT(!gradient->isRadial());
static void adjustGradientPointsForOffsetRange(
CSSGradientValue::GradientDesc& desc,
float firstOffset,
float lastOffset) {
ASSERT(firstOffset <= lastOffset);
const FloatPoint p0 = gradient->p0();
const FloatPoint p1 = gradient->p1();
const FloatPoint p0 = desc.p0;
const FloatPoint p1 = desc.p1;
const FloatSize d(p1 - p0);
// Linear offsets are relative to the [p0 , p1] segment.
gradient->setP0(p0 + d * firstOffset);
gradient->setP1(p0 + d * lastOffset);
desc.p0 = p0 + d * firstOffset;
desc.p1 = p0 + d * lastOffset;
}
// Update the radial gradient radii to align with the given offset range.
static void adjustGradientRadiiForOffsetRange(Gradient* gradient,
float firstOffset,
float lastOffset) {
ASSERT(gradient->isRadial());
static void adjustGradientRadiiForOffsetRange(
CSSGradientValue::GradientDesc& desc,
float firstOffset,
float lastOffset) {
ASSERT(firstOffset <= lastOffset);
// Radial offsets are relative to the [0 , endRadius] segment.
float adjustedR0 = gradient->endRadius() * firstOffset;
float adjustedR1 = gradient->endRadius() * lastOffset;
float adjustedR0 = desc.r1 * firstOffset;
float adjustedR1 = desc.r1 * lastOffset;
ASSERT(adjustedR0 <= adjustedR1);
// Unlike linear gradients (where we can adjust the points arbitrarily),
......@@ -364,7 +384,7 @@ static void adjustGradientRadiiForOffsetRange(Gradient* gradient,
if (adjustedR0 < 0) {
// For the non-repeat case, this can never happen: clampNegativeOffsets()
// ensures we don't have to deal with negative offsets at this point.
ASSERT(gradient->spreadMethod() == SpreadMethodRepeat);
DCHECK_EQ(desc.spreadMethod, SpreadMethodRepeat);
// When in repeat mode, we deal with it by repositioning both radii in the
// positive domain - shifting them by a multiple of the radius span (which
......@@ -378,16 +398,16 @@ static void adjustGradientRadiiForOffsetRange(Gradient* gradient,
ASSERT(adjustedR0 >= 0);
ASSERT(adjustedR1 >= adjustedR0);
gradient->setStartRadius(adjustedR0);
gradient->setEndRadius(adjustedR1);
desc.r0 = adjustedR0;
desc.r1 = adjustedR1;
}
void CSSGradientValue::addStops(Gradient* gradient,
void CSSGradientValue::addStops(CSSGradientValue::GradientDesc& desc,
const CSSToLengthConversionData& conversionData,
const LayoutObject& object) {
if (m_gradientType == CSSDeprecatedLinearGradient ||
m_gradientType == CSSDeprecatedRadialGradient) {
addDeprecatedStops(gradient, object);
addDeprecatedStops(desc, object);
return;
}
......@@ -397,12 +417,12 @@ void CSSGradientValue::addStops(Gradient* gradient,
bool hasHints = false;
FloatPoint gradientStart = gradient->p0();
FloatPoint gradientStart = desc.p0;
FloatPoint gradientEnd;
if (isLinearGradientValue())
gradientEnd = gradient->p1();
gradientEnd = desc.p1;
else if (isRadialGradientValue())
gradientEnd = gradientStart + FloatSize(gradient->endRadius(), 0);
gradientEnd = gradientStart + FloatSize(desc.r1, 0);
float gradientLength =
FloatSize(gradientStart - gradientEnd).diagonalLength();
......@@ -501,19 +521,19 @@ void CSSGradientValue::addStops(Gradient* gradient,
// At this point we have a fully resolved set of stops. Time to perform
// adjustments for repeat gradients and degenerate values if needed.
if (requiresStopsNormalization(stops, gradient)) {
if (requiresStopsNormalization(stops, desc)) {
// Negative offsets are only an issue for non-repeating radial gradients:
// linear gradient points can be repositioned arbitrarily, and for repeating
// radial gradients we shift the radii into equivalent positive values.
if (isRadialGradientValue() && !m_repeating)
clampNegativeOffsets(stops);
if (normalizeAndAddStops(stops, gradient)) {
if (normalizeAndAddStops(stops, desc)) {
if (isLinearGradientValue()) {
adjustGradientPointsForOffsetRange(gradient, stops.front().offset,
adjustGradientPointsForOffsetRange(desc, stops.front().offset,
stops.back().offset);
} else {
adjustGradientRadiiForOffsetRange(gradient, stops.front().offset,
adjustGradientRadiiForOffsetRange(desc, stops.front().offset,
stops.back().offset);
}
} else {
......@@ -522,7 +542,7 @@ void CSSGradientValue::addStops(Gradient* gradient,
} else {
// No normalization required, just add the current stops.
for (const auto& stop : stops)
gradient->addColorStop(stop.offset, stop.color);
desc.stops.emplace_back(stop.offset, stop.color);
}
}
......@@ -878,13 +898,16 @@ PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(
}
}
GradientDesc desc(firstPoint, secondPoint,
m_repeating ? SpreadMethodRepeat : SpreadMethodPad);
addStops(desc, conversionData, object);
RefPtr<Gradient> gradient =
Gradient::create(firstPoint, secondPoint,
m_repeating ? SpreadMethodRepeat : SpreadMethodPad,
Gradient::create(desc.p0, desc.p1, desc.spreadMethod,
Gradient::ColorInterpolation::Premultiplied);
// Now add the stops.
addStops(gradient.get(), conversionData, object);
gradient->addColorStops(desc.stops);
return gradient.release();
}
......@@ -1244,15 +1267,18 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(
DCHECK(std::isfinite(secondRadius.height()));
bool isDegenerate = !secondRadius.width() || !secondRadius.height();
RefPtr<Gradient> gradient =
Gradient::create(firstPoint, firstRadius, secondPoint,
isDegenerate ? 0 : secondRadius.width(),
isDegenerate ? 1 : secondRadius.aspectRatio(),
m_repeating ? SpreadMethodRepeat : SpreadMethodPad,
Gradient::ColorInterpolation::Premultiplied);
GradientDesc desc(firstPoint, secondPoint, firstRadius,
isDegenerate ? 0 : secondRadius.width(),
m_repeating ? SpreadMethodRepeat : SpreadMethodPad);
addStops(desc, conversionData, object);
RefPtr<Gradient> gradient = Gradient::create(
desc.p0, desc.r0, desc.p1, desc.r1,
isDegenerate ? 1 : secondRadius.aspectRatio(), desc.spreadMethod,
Gradient::ColorInterpolation::Premultiplied);
// Now add the stops.
addStops(gradient.get(), conversionData, object);
gradient->addColorStops(desc.stops);
return gradient.release();
}
......
......@@ -114,6 +114,8 @@ class CSSGradientValue : public CSSImageGeneratorValue {
DECLARE_TRACE_AFTER_DISPATCH();
struct GradientDesc;
protected:
CSSGradientValue(ClassType classType,
CSSGradientRepeat repeat,
......@@ -123,10 +125,10 @@ class CSSGradientValue : public CSSImageGeneratorValue {
m_gradientType(gradientType),
m_repeating(repeat == Repeating) {}
void addStops(Gradient*,
void addStops(GradientDesc&,
const CSSToLengthConversionData&,
const LayoutObject&);
void addDeprecatedStops(Gradient*, const LayoutObject&);
void addDeprecatedStops(GradientDesc&, const LayoutObject&);
// Resolve points/radii to front end values.
FloatPoint computeEndPoint(CSSValue*,
......
......@@ -96,37 +96,9 @@ class PLATFORM_EXPORT Gradient : public RefCounted<Gradient> {
const FloatPoint& p0() const { return m_p0; }
const FloatPoint& p1() const { return m_p1; }
void setP0(const FloatPoint& p) {
if (m_p0 == p)
return;
m_p0 = p;
}
void setP1(const FloatPoint& p) {
if (m_p1 == p)
return;
m_p1 = p;
}
float startRadius() const { return m_r0; }
float endRadius() const { return m_r1; }
void setStartRadius(float r) {
if (m_r0 == r)
return;
m_r0 = r;
}
void setEndRadius(float r) {
if (m_r1 == r)
return;
m_r1 = r;
}
void applyToFlags(PaintFlags&, const SkMatrix& localMatrix);
GradientSpreadMethod spreadMethod() const { return m_spreadMethod; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment