#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/css/css_gradient_value.h"
#include <algorithm>
#include <tuple>
#include <utility>
#include "base/memory/values_equivalent.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "third_party/blink/renderer/core/css/css_color.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
#include "third_party/blink/renderer/core/css/css_math_function_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
#include "third_party/blink/renderer/core/css/css_value_pair.h"
#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "third_party/blink/renderer/core/css/properties/longhands.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/text_link_colors.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/gradient.h"
#include "third_party/blink/renderer/platform/graphics/gradient_generated_image.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "ui/gfx/geometry/size.h"
namespace blink::cssvalue {
namespace {
bool ColorIsDerivedFromElement(const CSSIdentifierValue& value) { … }
bool AppendPosition(StringBuilder& result,
const CSSValue* x,
const CSSValue* y,
bool wrote_something) { … }
}
bool CSSGradientColorStop::IsCacheable() const { … }
void CSSGradientColorStop::Trace(Visitor* visitor) const { … }
scoped_refptr<Image> CSSGradientValue::GetImage(
const ImageResourceObserver& client,
const Document& document,
const ComputedStyle& style,
const ContainerSizes& container_sizes,
const gfx::SizeF& size) const { … }
static inline bool CompareStops(
const CSSGradientColorStop& a,
const CSSGradientColorStop& b,
const CSSToLengthConversionData& conversion_data) { … }
struct GradientStop { … };
struct CSSGradientValue::GradientDesc { … };
static void ReplaceColorHintsWithColorStops(
Vector<GradientStop>& stops,
const HeapVector<CSSGradientColorStop, 2>& css_gradient_stops,
Color::ColorSpace color_interpolation_space,
Color::HueInterpolationMethod hue_interpolation_method) { … }
static Color ResolveStopColor(const CSSValue& stop_color,
const Document& document,
const ComputedStyle& style) { … }
void CSSGradientValue::AddDeprecatedStops(
GradientDesc& desc,
const Document& document,
const ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) const { … }
static const CSSValue* GetComputedStopColor(const CSSValue& color,
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) { … }
void CSSGradientValue::AddComputedStops(
const ComputedStyle& style,
bool allow_visited_style,
const HeapVector<CSSGradientColorStop, 2>& stops,
CSSValuePhase value_phase) { … }
namespace {
bool RequiresStopsNormalization(const Vector<GradientStop>& stops,
CSSGradientValue::GradientDesc& desc) { … }
bool NormalizeAndAddStops(const Vector<GradientStop>& stops,
CSSGradientValue::GradientDesc& desc) { … }
void ClampNegativeOffsets(
Vector<GradientStop>& stops,
Color::ColorSpace color_interpolation_space,
Color::HueInterpolationMethod hue_interpolation_method) { … }
gfx::Vector2dF operator*(const gfx::Vector2dF& v, float scale) { … }
template <typename T>
std::tuple<T, T> AdjustedGradientDomainForOffsetRange(const T& v0,
const T& v1,
float first_offset,
float last_offset) { … }
void AdjustGradientRadiiForOffsetRange(CSSGradientValue::GradientDesc& desc,
float first_offset,
float last_offset) { … }
}
void CSSGradientValue::AddStops(
CSSGradientValue::GradientDesc& desc,
const CSSToLengthConversionData& conversion_data,
const Document& document,
const ComputedStyle& style) const { … }
static float PositionFromValue(const CSSValue* value,
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size,
bool is_horizontal) { … }
static gfx::PointF ComputeEndPoint(
const CSSValue* horizontal,
const CSSValue* vertical,
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size) { … }
bool CSSGradientValue::KnownToBeOpaque(const Document& document,
const ComputedStyle& style) const { … }
CSSGradientValue* CSSGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) const { … }
Vector<Color> CSSGradientValue::GetStopColors(
const Document& document,
const ComputedStyle& style) const { … }
void CSSGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { … }
bool CSSGradientValue::ShouldSerializeColorSpace() const { … }
String CSSLinearGradientValue::CustomCSSText() const { … }
static void EndPointsFromAngle(float angle_deg,
const gfx::SizeF& size,
gfx::PointF& first_point,
gfx::PointF& second_point,
CSSGradientType type) { … }
scoped_refptr<Gradient> CSSLinearGradientValue::CreateGradient(
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size,
const Document& document,
const ComputedStyle& style) const { … }
bool CSSLinearGradientValue::Equals(const CSSLinearGradientValue& other) const { … }
CSSLinearGradientValue* CSSLinearGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) const { … }
static bool IsUsingCurrentColor(
const HeapVector<CSSGradientColorStop, 2>& stops) { … }
static bool IsUsingContainerRelativeUnits(const CSSValue* value) { … }
static bool IsUsingContainerRelativeUnits(
const HeapVector<CSSGradientColorStop, 2>& stops) { … }
bool CSSLinearGradientValue::IsUsingCurrentColor() const { … }
bool CSSLinearGradientValue::IsUsingContainerRelativeUnits() const { … }
void CSSLinearGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { … }
void CSSGradientValue::AppendCSSTextForColorStops(
StringBuilder& result,
bool requires_separator) const { … }
void CSSGradientValue::AppendCSSTextForDeprecatedColorStops(
StringBuilder& result) const { … }
bool CSSGradientValue::Equals(const CSSGradientValue& other) const { … }
String CSSRadialGradientValue::CustomCSSText() const { … }
namespace {
float ResolveRadius(const CSSPrimitiveValue* radius,
const CSSToLengthConversionData& conversion_data,
float* width_or_height = nullptr) { … }
enum EndShapeType { … };
gfx::SizeF RadiusToSide(const gfx::PointF& point,
const gfx::SizeF& size,
EndShapeType shape,
bool (*compare)(float, float)) { … }
inline gfx::SizeF EllipseRadius(const gfx::Vector2dF& offset_from_center,
float aspect_ratio) { … }
gfx::SizeF RadiusToCorner(const gfx::PointF& point,
const gfx::SizeF& size,
EndShapeType shape,
bool (*compare)(float, float)) { … }
}
scoped_refptr<Gradient> CSSRadialGradientValue::CreateGradient(
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size,
const Document& document,
const ComputedStyle& style) const { … }
namespace {
bool EqualIdentifiersWithDefault(const CSSIdentifierValue* id_a,
const CSSIdentifierValue* id_b,
CSSValueID default_id) { … }
}
bool CSSRadialGradientValue::Equals(const CSSRadialGradientValue& other) const { … }
CSSRadialGradientValue* CSSRadialGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) const { … }
bool CSSRadialGradientValue::IsUsingCurrentColor() const { … }
bool CSSRadialGradientValue::IsUsingContainerRelativeUnits() const { … }
void CSSRadialGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { … }
String CSSConicGradientValue::CustomCSSText() const { … }
scoped_refptr<Gradient> CSSConicGradientValue::CreateGradient(
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size,
const Document& document,
const ComputedStyle& style) const { … }
bool CSSConicGradientValue::Equals(const CSSConicGradientValue& other) const { … }
CSSConicGradientValue* CSSConicGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) const { … }
bool CSSConicGradientValue::IsUsingCurrentColor() const { … }
bool CSSConicGradientValue::IsUsingContainerRelativeUnits() const { … }
void CSSConicGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const { … }
bool CSSConstantGradientValue::Equals(
const CSSConstantGradientValue& other) const { … }
void CSSConstantGradientValue::TraceAfterDispatch(
blink::Visitor* visitor) const { … }
bool CSSConstantGradientValue::KnownToBeOpaque(
const Document& document,
const ComputedStyle& style) const { … }
scoped_refptr<Gradient> CSSConstantGradientValue::CreateGradient(
const CSSToLengthConversionData& conversion_data,
const gfx::SizeF& size,
const Document& document,
const ComputedStyle& style) const { … }
CSSConstantGradientValue* CSSConstantGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style,
CSSValuePhase value_phase) const { … }
}