blob: 47ee78002ebaf5959e4b5691aa00be6691733b2b [file] [log] [blame]
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CSSGradientValue_h
#define CSSGradientValue_h
#include "base/memory/scoped_refptr.h"
#include "core/css/CSSIdentifierValue.h"
#include "core/css/CSSImageGeneratorValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "platform/wtf/Vector.h"
namespace blink {
class Color;
class Gradient;
class Document;
class LayoutObject;
namespace cssvalue {
enum CSSGradientType {
kCSSDeprecatedLinearGradient,
kCSSDeprecatedRadialGradient,
kCSSPrefixedLinearGradient,
kCSSPrefixedRadialGradient,
kCSSLinearGradient,
kCSSRadialGradient,
kCSSConicGradient
};
enum CSSGradientRepeat { kNonRepeating, kRepeating };
// This struct is stack allocated and allocated as part of vectors.
// When allocated on the stack its members are found by conservative
// stack scanning. When allocated as part of Vectors in heap-allocated
// objects its members are visited via the containing object's
// (CSSGradientValue) traceAfterDispatch method.
//
// http://www.w3.org/TR/css3-images/#color-stop-syntax
struct CSSGradientColorStop {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
bool operator==(const CSSGradientColorStop& other) const {
return DataEquivalent(color_, other.color_) &&
DataEquivalent(offset_, other.offset_);
}
bool IsHint() const {
DCHECK(color_ || offset_);
return !color_;
}
bool IsCacheable() const;
void Trace(blink::Visitor*);
Member<const CSSPrimitiveValue> offset_; // percentage | length | angle
Member<const CSSValue> color_;
};
} // namespace cssvalue
} // namespace blink
// We have to declare the VectorTraits specialization before CSSGradientValue
// declares its inline capacity vector below.
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
blink::cssvalue::CSSGradientColorStop);
namespace blink {
namespace cssvalue {
class CSSGradientValue : public CSSImageGeneratorValue {
public:
scoped_refptr<Image> GetImage(const ImageResourceObserver&,
const Document&,
const ComputedStyle&,
const LayoutSize&);
void AddStop(const CSSGradientColorStop& stop) {
stops_.push_back(stop);
is_cacheable_ = is_cacheable_ && stop.IsCacheable();
}
size_t StopCount() const { return stops_.size(); }
bool IsRepeating() const { return repeating_; }
CSSGradientType GradientType() const { return gradient_type_; }
bool IsFixedSize() const { return false; }
FloatSize FixedSize(const Document&) const { return FloatSize(); }
bool IsPending() const { return false; }
bool KnownToBeOpaque(const Document&, const ComputedStyle&) const;
void LoadSubimages(const Document&) {}
void GetStopColors(Vector<Color>& stop_colors, const LayoutObject&) const;
void TraceAfterDispatch(blink::Visitor*);
struct GradientDesc;
protected:
CSSGradientValue(ClassType class_type,
CSSGradientRepeat repeat,
CSSGradientType gradient_type)
: CSSImageGeneratorValue(class_type),
gradient_type_(gradient_type),
repeating_(repeat == kRepeating),
stops_sorted_(false),
is_cacheable_(true) {}
void AddStops(GradientDesc&,
const CSSToLengthConversionData&,
const LayoutObject&);
void AddDeprecatedStops(GradientDesc&, const LayoutObject&);
void AppendCSSTextForColorStops(StringBuilder&,
bool requires_separator) const;
void AppendCSSTextForDeprecatedColorStops(StringBuilder&) const;
// Stops
HeapVector<CSSGradientColorStop, 2> stops_;
CSSGradientType gradient_type_;
bool repeating_ : 1;
bool stops_sorted_ : 1;
bool is_cacheable_ : 1;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSGradientValue, IsGradientValue());
class CSSLinearGradientValue final : public CSSGradientValue {
public:
static CSSGradientValue* Create(
const CSSValue* first_x,
const CSSValue* first_y,
const CSSValue* second_x,
const CSSValue* second_y,
const CSSPrimitiveValue* angle,
CSSGradientRepeat repeat,
CSSGradientType gradient_type = kCSSLinearGradient) {
return new CSSLinearGradientValue(first_x, first_y, second_x, second_y,
angle, repeat, gradient_type);
}
String CustomCSSText() const;
// Create the gradient for a given size.
scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
const LayoutSize&,
const LayoutObject&);
bool Equals(const CSSLinearGradientValue&) const;
void TraceAfterDispatch(blink::Visitor*);
private:
CSSLinearGradientValue(const CSSValue* first_x,
const CSSValue* first_y,
const CSSValue* second_x,
const CSSValue* second_y,
const CSSPrimitiveValue* angle,
CSSGradientRepeat repeat,
CSSGradientType gradient_type = kCSSLinearGradient)
: CSSGradientValue(kLinearGradientClass, repeat, gradient_type),
first_x_(first_x),
first_y_(first_y),
second_x_(second_x),
second_y_(second_y),
angle_(angle) {}
// Any of these may be null.
Member<const CSSValue> first_x_;
Member<const CSSValue> first_y_;
Member<const CSSValue> second_x_;
Member<const CSSValue> second_y_;
Member<const CSSPrimitiveValue> angle_;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSLinearGradientValue, IsLinearGradientValue());
class CSSRadialGradientValue final : public CSSGradientValue {
public:
static CSSGradientValue* Create(
const CSSValue* first_x,
const CSSValue* first_y,
const CSSPrimitiveValue* first_radius,
const CSSValue* second_x,
const CSSValue* second_y,
const CSSPrimitiveValue* second_radius,
CSSGradientRepeat repeat,
CSSGradientType gradient_type = kCSSRadialGradient) {
return new CSSRadialGradientValue(first_x, first_y, first_radius, second_x,
second_y, second_radius, nullptr, nullptr,
nullptr, nullptr, repeat, gradient_type);
}
static CSSGradientValue* Create(const CSSValue* center_x,
const CSSValue* center_y,
const CSSIdentifierValue* shape,
const CSSIdentifierValue* sizing_behavior,
const CSSPrimitiveValue* horizontal_size,
const CSSPrimitiveValue* vertical_size,
CSSGradientRepeat repeat,
CSSGradientType gradient_type) {
return new CSSRadialGradientValue(
center_x, center_y, nullptr, center_x, center_y, nullptr, shape,
sizing_behavior, horizontal_size, vertical_size, repeat, gradient_type);
}
String CustomCSSText() const;
void SetShape(CSSIdentifierValue* val) { shape_ = val; }
void SetSizingBehavior(CSSIdentifierValue* val) { sizing_behavior_ = val; }
void SetEndHorizontalSize(CSSPrimitiveValue* val) {
end_horizontal_size_ = val;
}
void SetEndVerticalSize(CSSPrimitiveValue* val) { end_vertical_size_ = val; }
// Create the gradient for a given size.
scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
const LayoutSize&,
const LayoutObject&);
bool Equals(const CSSRadialGradientValue&) const;
void TraceAfterDispatch(blink::Visitor*);
private:
CSSRadialGradientValue(const CSSValue* first_x,
const CSSValue* first_y,
const CSSPrimitiveValue* first_radius,
const CSSValue* second_x,
const CSSValue* second_y,
const CSSPrimitiveValue* second_radius,
const CSSIdentifierValue* shape,
const CSSIdentifierValue* sizing_behavior,
const CSSPrimitiveValue* horizontal_size,
const CSSPrimitiveValue* vertical_size,
CSSGradientRepeat repeat,
CSSGradientType gradient_type = kCSSRadialGradient)
: CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
first_x_(first_x),
first_y_(first_y),
second_x_(second_x),
second_y_(second_y),
first_radius_(first_radius),
second_radius_(second_radius),
shape_(shape),
sizing_behavior_(sizing_behavior),
end_horizontal_size_(horizontal_size),
end_vertical_size_(vertical_size) {}
// Any of these may be null.
Member<const CSSValue> first_x_;
Member<const CSSValue> first_y_;
Member<const CSSValue> second_x_;
Member<const CSSValue> second_y_;
// These may be null for non-deprecated gradients.
Member<const CSSPrimitiveValue> first_radius_;
Member<const CSSPrimitiveValue> second_radius_;
// The below are only used for non-deprecated gradients. Any of them may be
// null.
Member<const CSSIdentifierValue> shape_;
Member<const CSSIdentifierValue> sizing_behavior_;
Member<const CSSPrimitiveValue> end_horizontal_size_;
Member<const CSSPrimitiveValue> end_vertical_size_;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSRadialGradientValue, IsRadialGradientValue());
class CSSConicGradientValue final : public CSSGradientValue {
public:
static CSSGradientValue* Create(const CSSValue* x,
const CSSValue* y,
const CSSPrimitiveValue* from_angle,
CSSGradientRepeat repeat) {
return new CSSConicGradientValue(x, y, from_angle, repeat);
}
String CustomCSSText() const;
// Create the gradient for a given size.
scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
const LayoutSize&,
const LayoutObject&);
bool Equals(const CSSConicGradientValue&) const;
void TraceAfterDispatch(blink::Visitor*);
private:
CSSConicGradientValue(const CSSValue* x,
const CSSValue* y,
const CSSPrimitiveValue* from_angle,
CSSGradientRepeat repeat)
: CSSGradientValue(kConicGradientClass, repeat, kCSSConicGradient),
x_(x),
y_(y),
from_angle_(from_angle) {}
// Any of these may be null.
Member<const CSSValue> x_;
Member<const CSSValue> y_;
Member<const CSSPrimitiveValue> from_angle_;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSConicGradientValue, IsConicGradientValue());
} // namespace cssvalue
} // namespace blink
#endif // CSSGradientValue_h