Commit dcbfc950 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Refactor computed <paint> value handling

Combine all the fields that make up a <paint> into a class: SVGPaint.
Move the bulk of the style builder function for <paint> from the
template to StyleBuilderConverter. This should make future work on
<paint> resolution easier.
Also split the existing setters on {SVG,}ComputedStyle to avoid having
bools to indicate if the "visited" portion should be set or not. The
new way more closely resemble other color properties.
Add accessors to SVGPaint to both make code easier to read, and reduce
the dependence on SVGPaintType.

Bug: 769774
Change-Id: Ifad043c9e423f0fc7aa79fef78e635b2abb4636c
Reviewed-on: https://chromium-review.googlesource.com/961062Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#543333}
parent dbbbaa94
......@@ -278,56 +278,28 @@ namespace blink {
{% macro apply_svg_paint(property_id, paint_type) %}
{% set property = properties_by_id[property_id] %}
{% set visited_link_setter = 'SetVisitedLink' + paint_type %}
{{declare_initial_function(property_id)}} {
{{set_value(property)}}(
SVGComputedStyle::Initial{{paint_type}}Type(),
SVGComputedStyle::Initial{{paint_type}}Color(),
SVGComputedStyle::Initial{{paint_type}}Uri(),
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(SVGComputedStyle::Initial{{paint_type}}());
if (state.ApplyPropertyToVisitedLinkStyle())
state.Style()->AccessSVGStyle().{{visited_link_setter}}(SVGComputedStyle::Initial{{paint_type}}());
}
{{declare_inherit_function(property_id)}} {
const SVGComputedStyle& svgParentStyle = state.ParentStyle()->SvgStyle();
{{set_value(property)}}(
svgParentStyle.{{paint_type}}Type(),
svgParentStyle.{{paint_type}}Color(),
svgParentStyle.{{paint_type}}Uri(),
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
const SVGComputedStyle& parent_svg_style = state.ParentStyle()->SvgStyle();
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(parent_svg_style.{{paint_type}}());
if (state.ApplyPropertyToVisitedLinkStyle())
state.Style()->AccessSVGStyle().{{visited_link_setter}}(parent_svg_style.{{paint_type}}());
}
{{declare_value_function(property_id)}} {
const CSSValue* localValue = &value;
String url;
if (value.IsValueList()) {
const CSSValueList& list = ToCSSValueList(value);
DCHECK_EQ(list.length(), 2U);
url = ToCSSURIValue(list.Item(0)).Value();
localValue = &list.Item(1);
}
Color color;
SVGPaintType paintType = SVG_PAINTTYPE_RGBCOLOR;
if (localValue->IsURIValue()) {
paintType = SVG_PAINTTYPE_URI;
url = ToCSSURIValue(localValue)->Value();
} else if (localValue->IsIdentifierValue() &&
ToCSSIdentifierValue(localValue)->GetValueID() == CSSValueNone) {
paintType = url.IsEmpty() ? SVG_PAINTTYPE_NONE : SVG_PAINTTYPE_URI_NONE;
} else if (localValue->IsIdentifierValue() &&
ToCSSIdentifierValue(localValue)->GetValueID() == CSSValueCurrentcolor) {
color = state.Style()->GetColor();
paintType = url.IsEmpty() ? SVG_PAINTTYPE_CURRENTCOLOR
: SVG_PAINTTYPE_URI_CURRENTCOLOR;
} else {
color = StyleBuilderConverter::ConvertColor(state, *localValue);
paintType = url.IsEmpty() ? SVG_PAINTTYPE_RGBCOLOR
: SVG_PAINTTYPE_URI_RGBCOLOR;
}
{{set_value(property)}}(paintType, color, url,
state.ApplyPropertyToRegularStyle(),
state.ApplyPropertyToVisitedLinkStyle());
SVGPaint paint = StyleBuilderConverter::ConvertSVGPaint(state, value);
if (state.ApplyPropertyToRegularStyle())
{{set_value(property)}}(paint);
if (state.ApplyPropertyToVisitedLinkStyle())
state.Style()->AccessSVGStyle().{{visited_link_setter}}(paint);
}
{% endmacro %}
{{apply_svg_paint('CSSPropertyFill', 'FillPaint')}}
......
......@@ -17,19 +17,15 @@
namespace blink {
namespace {
static bool GetColorFromPaint(const SVGPaintType type,
const Color color,
StyleColor& result) {
switch (type) {
case SVG_PAINTTYPE_RGBCOLOR:
result = color;
return true;
case SVG_PAINTTYPE_CURRENTCOLOR:
result = StyleColor::CurrentColor();
return true;
default:
return false;
}
static bool GetColorFromPaint(const SVGPaint& paint, StyleColor& result) {
if (!paint.IsColor())
return false;
if (paint.HasCurrentColor())
result = StyleColor::CurrentColor();
else
result = paint.GetColor();
return true;
}
bool GetColor(const CSSProperty& property,
......@@ -37,16 +33,15 @@ bool GetColor(const CSSProperty& property,
StyleColor& result) {
switch (property.PropertyID()) {
case CSSPropertyFill:
return GetColorFromPaint(style.SvgStyle().FillPaintType(),
style.SvgStyle().FillPaintColor(), result);
return GetColorFromPaint(style.SvgStyle().FillPaint(), result);
case CSSPropertyStroke:
return GetColorFromPaint(style.SvgStyle().StrokePaintType(),
style.SvgStyle().StrokePaintColor(), result);
return GetColorFromPaint(style.SvgStyle().StrokePaint(), result);
default:
NOTREACHED();
return false;
}
}
} // namespace
InterpolationValue CSSPaintInterpolationType::MaybeConvertNeutral(
......@@ -143,14 +138,15 @@ void CSSPaintInterpolationType::ApplyStandardPropertyValue(
StyleResolverState& state) const {
Color color = CSSColorInterpolationType::ResolveInterpolableColor(
interpolable_color, state);
SVGComputedStyle& mutable_svg_style = state.Style()->AccessSVGStyle();
switch (CssProperty().PropertyID()) {
case CSSPropertyFill:
state.Style()->AccessSVGStyle().SetFillPaint(SVG_PAINTTYPE_RGBCOLOR,
color, String(), true, true);
mutable_svg_style.SetFillPaint(SVGPaint(color));
mutable_svg_style.SetVisitedLinkFillPaint(SVGPaint(color));
break;
case CSSPropertyStroke:
state.Style()->AccessSVGStyle().SetStrokePaint(
SVG_PAINTTYPE_RGBCOLOR, color, String(), true, true);
mutable_svg_style.SetStrokePaint(SVGPaint(color));
mutable_svg_style.SetVisitedLinkStrokePaint(SVGPaint(color));
break;
default:
NOTREACHED();
......
......@@ -134,14 +134,9 @@ bool CSSPropertyEquality::PropertiesEqual(const PropertyHandle& property,
case CSSPropertyFill: {
const SVGComputedStyle& a_svg = a.SvgStyle();
const SVGComputedStyle& b_svg = b.SvgStyle();
return a_svg.FillPaintType() == b_svg.FillPaintType() &&
(a_svg.FillPaintType() != SVG_PAINTTYPE_RGBCOLOR ||
a_svg.FillPaintColor() == b_svg.FillPaintColor()) &&
a_svg.VisitedLinkFillPaintType() ==
b_svg.VisitedLinkFillPaintType() &&
(a_svg.VisitedLinkFillPaintType() != SVG_PAINTTYPE_RGBCOLOR ||
a_svg.VisitedLinkFillPaintColor() ==
b_svg.VisitedLinkFillPaintColor());
return a_svg.FillPaint().EqualTypeOrColor(b_svg.FillPaint()) &&
a_svg.VisitedLinkFillPaint().EqualTypeOrColor(
b_svg.VisitedLinkFillPaint());
}
case CSSPropertyFillOpacity:
return a.FillOpacity() == b.FillOpacity();
......@@ -248,14 +243,9 @@ bool CSSPropertyEquality::PropertiesEqual(const PropertyHandle& property,
case CSSPropertyStroke: {
const SVGComputedStyle& a_svg = a.SvgStyle();
const SVGComputedStyle& b_svg = b.SvgStyle();
return a_svg.StrokePaintType() == b_svg.StrokePaintType() &&
(a_svg.StrokePaintType() != SVG_PAINTTYPE_RGBCOLOR ||
a_svg.StrokePaintColor() == b_svg.StrokePaintColor()) &&
a_svg.VisitedLinkStrokePaintType() ==
b_svg.VisitedLinkStrokePaintType() &&
(a_svg.VisitedLinkStrokePaintType() != SVG_PAINTTYPE_RGBCOLOR ||
a_svg.VisitedLinkStrokePaintColor() ==
b_svg.VisitedLinkStrokePaintColor());
return a_svg.StrokePaint().EqualTypeOrColor(b_svg.StrokePaint()) &&
a_svg.VisitedLinkStrokePaint().EqualTypeOrColor(
b_svg.VisitedLinkStrokePaint());
}
case CSSPropertyStrokeDasharray:
return a.StrokeDashArray() == b.StrokeDashArray();
......
......@@ -1866,27 +1866,25 @@ CSSValue* ComputedStyleUtils::PaintOrderToCSSValueList(
}
CSSValue* ComputedStyleUtils::AdjustSVGPaintForCurrentColor(
SVGPaintType paint_type,
const String& url,
const Color& color,
const SVGPaint& paint,
const Color& current_color) {
if (paint_type >= SVG_PAINTTYPE_URI_NONE) {
if (paint.type >= SVG_PAINTTYPE_URI_NONE) {
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
values->Append(*CSSURIValue::Create(AtomicString(url)));
if (paint_type == SVG_PAINTTYPE_URI_NONE)
values->Append(*CSSURIValue::Create(AtomicString(paint.GetUrl())));
if (paint.type == SVG_PAINTTYPE_URI_NONE)
values->Append(*CSSIdentifierValue::Create(CSSValueNone));
else if (paint_type == SVG_PAINTTYPE_URI_CURRENTCOLOR)
else if (paint.type == SVG_PAINTTYPE_URI_CURRENTCOLOR)
values->Append(*CSSColorValue::Create(current_color.Rgb()));
else if (paint_type == SVG_PAINTTYPE_URI_RGBCOLOR)
values->Append(*CSSColorValue::Create(color.Rgb()));
else if (paint.type == SVG_PAINTTYPE_URI_RGBCOLOR)
values->Append(*CSSColorValue::Create(paint.GetColor().Rgb()));
return values;
}
if (paint_type == SVG_PAINTTYPE_NONE)
if (paint.type == SVG_PAINTTYPE_NONE)
return CSSIdentifierValue::Create(CSSValueNone);
if (paint_type == SVG_PAINTTYPE_CURRENTCOLOR)
if (paint.type == SVG_PAINTTYPE_CURRENTCOLOR)
return CSSColorValue::Create(current_color.Rgb());
return CSSColorValue::Create(color.Rgb());
return CSSColorValue::Create(paint.GetColor().Rgb());
}
CSSValue* ComputedStyleUtils::ValueForShadowData(const ShadowData& shadow,
......
......@@ -149,10 +149,7 @@ class ComputedStyleUtils {
static CSSValue* StrokeDashArrayToCSSValueList(const SVGDashArray&,
const ComputedStyle&);
static CSSValue* PaintOrderToCSSValueList(const SVGComputedStyle&);
static CSSValue* AdjustSVGPaintForCurrentColor(SVGPaintType,
const String&,
const Color&,
const Color&);
static CSSValue* AdjustSVGPaintForCurrentColor(const SVGPaint&, const Color&);
static CSSValue* ValueForShadowData(const ShadowData&,
const ComputedStyle&,
bool use_spread);
......
......@@ -24,8 +24,7 @@ const CSSValue* Fill::CSSValueFromComputedStyleInternal(
Node* styled_node,
bool allow_visited_style) const {
return ComputedStyleUtils::AdjustSVGPaintForCurrentColor(
svg_style.FillPaintType(), svg_style.FillPaintUri(),
svg_style.FillPaintColor(), style.GetColor());
svg_style.FillPaint(), style.GetColor());
}
} // namespace CSSLonghand
......
......@@ -24,8 +24,7 @@ const CSSValue* Stroke::CSSValueFromComputedStyleInternal(
Node* styled_node,
bool allow_visited_style) const {
return ComputedStyleUtils::AdjustSVGPaintForCurrentColor(
svg_style.StrokePaintType(), svg_style.StrokePaintUri(),
svg_style.StrokePaintColor(), style.GetColor());
svg_style.StrokePaint(), style.GetColor());
}
} // namespace CSSLonghand
......
......@@ -1396,6 +1396,38 @@ StyleAutoColor StyleBuilderConverter::ConvertStyleAutoColor(
value, Color(), for_visited_link);
}
SVGPaint StyleBuilderConverter::ConvertSVGPaint(StyleResolverState& state,
const CSSValue& value) {
const CSSValue* local_value = &value;
SVGPaint paint;
if (value.IsValueList()) {
const CSSValueList& list = ToCSSValueList(value);
DCHECK_EQ(list.length(), 2u);
paint.url = ToCSSURIValue(list.Item(0)).Value();
local_value = &list.Item(1);
}
if (local_value->IsURIValue()) {
paint.type = SVG_PAINTTYPE_URI;
paint.url = ToCSSURIValue(local_value)->Value();
} else if (local_value->IsIdentifierValue() &&
ToCSSIdentifierValue(local_value)->GetValueID() == CSSValueNone) {
paint.type =
paint.url.IsEmpty() ? SVG_PAINTTYPE_NONE : SVG_PAINTTYPE_URI_NONE;
} else if (local_value->IsIdentifierValue() &&
ToCSSIdentifierValue(local_value)->GetValueID() ==
CSSValueCurrentcolor) {
paint.color = state.Style()->GetColor();
paint.type = paint.url.IsEmpty() ? SVG_PAINTTYPE_CURRENTCOLOR
: SVG_PAINTTYPE_URI_CURRENTCOLOR;
} else {
paint.color = ConvertColor(state, *local_value);
paint.type = paint.url.IsEmpty() ? SVG_PAINTTYPE_RGBCOLOR
: SVG_PAINTTYPE_URI_RGBCOLOR;
}
return paint;
}
TextEmphasisPosition StyleBuilderConverter::ConvertTextTextEmphasisPosition(
StyleResolverState& state,
const CSSValue& value) {
......@@ -1414,6 +1446,7 @@ TextEmphasisPosition StyleBuilderConverter::ConvertTextTextEmphasisPosition(
return TextEmphasisPosition::kUnderLeft;
return TextEmphasisPosition::kOverRight;
}
float StyleBuilderConverter::ConvertTextStrokeWidth(StyleResolverState& state,
const CSSValue& value) {
if (value.IsIdentifierValue() && ToCSSIdentifierValue(value).GetValueID()) {
......
......@@ -192,6 +192,7 @@ class StyleBuilderConverter {
static StyleAutoColor ConvertStyleAutoColor(StyleResolverState&,
const CSSValue&,
bool for_visited_link = false);
static SVGPaint ConvertSVGPaint(StyleResolverState&, const CSSValue&);
static TextEmphasisPosition ConvertTextTextEmphasisPosition(
StyleResolverState&,
const CSSValue&);
......
......@@ -66,57 +66,33 @@ void SVGPaintServer::PrependTransform(const AffineTransform& transform) {
static SVGPaintDescription RequestPaint(const LayoutObject& object,
const ComputedStyle& style,
LayoutSVGResourceMode mode) {
// If we have no style at all, ignore it.
bool apply_to_fill = mode == kApplyToFillMode;
const SVGComputedStyle& svg_style = style.SvgStyle();
const SVGPaint& paint =
apply_to_fill ? svg_style.FillPaint() : svg_style.StrokePaint();
const SVGPaint& visited_paint = apply_to_fill
? svg_style.VisitedLinkFillPaint()
: svg_style.VisitedLinkStrokePaint();
// If we have no fill/stroke, return 0.
if (mode == kApplyToFillMode) {
if (!svg_style.HasFill())
return SVGPaintDescription();
} else {
if (!svg_style.HasStroke())
return SVGPaintDescription();
}
// If we have no, ignore it.
if (paint.IsNone())
return SVGPaintDescription();
bool apply_to_fill = mode == kApplyToFillMode;
SVGPaintType paint_type =
apply_to_fill ? svg_style.FillPaintType() : svg_style.StrokePaintType();
DCHECK_NE(paint_type, SVG_PAINTTYPE_NONE);
Color color;
bool has_color = false;
switch (paint_type) {
case SVG_PAINTTYPE_CURRENTCOLOR:
case SVG_PAINTTYPE_URI_CURRENTCOLOR:
// The keyword `currentcolor` takes its value from the value of the
// `color` property on the same element.
color = style.VisitedDependentColor(GetCSSPropertyColor());
has_color = true;
break;
case SVG_PAINTTYPE_RGBCOLOR:
case SVG_PAINTTYPE_URI_RGBCOLOR:
color = apply_to_fill ? svg_style.FillPaintColor()
: svg_style.StrokePaintColor();
has_color = true;
break;
default:
break;
}
Color color = paint.GetColor();
bool has_color = paint.HasColor();
if (paint.HasCurrentColor())
color = style.VisitedDependentColor(GetCSSPropertyColor());
if (style.InsideLink() == EInsideLink::kInsideVisitedLink) {
// FIXME: This code doesn't support the uri component of the visited link
// paint, https://bugs.webkit.org/show_bug.cgi?id=70006
SVGPaintType visited_paint_type =
apply_to_fill ? svg_style.VisitedLinkFillPaintType()
: svg_style.VisitedLinkStrokePaintType();
// For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the
// 'visitedColor'.
if (visited_paint_type < SVG_PAINTTYPE_URI_NONE &&
visited_paint_type != SVG_PAINTTYPE_CURRENTCOLOR) {
const Color& visited_color =
apply_to_fill ? svg_style.VisitedLinkFillPaintColor()
: svg_style.VisitedLinkStrokePaintColor();
// If the color (primary or fallback) is 'currentcolor', then |color|
// already contains the 'visited color'.
if (!visited_paint.HasUrl() && !visited_paint.HasCurrentColor()) {
const Color& visited_color = visited_paint.GetColor();
color = Color(visited_color.Red(), visited_color.Green(),
visited_color.Blue(), color.Alpha());
has_color = true;
......@@ -124,8 +100,8 @@ static SVGPaintDescription RequestPaint(const LayoutObject& object,
}
// If the primary resource is just a color, return immediately.
if (paint_type < SVG_PAINTTYPE_URI_NONE) {
// |paintType| will be either <current-color> or <rgb-color> here - both of
if (!paint.HasUrl()) {
// |paint.type| will be either <current-color> or <rgb-color> here - both of
// which will have a color.
DCHECK(has_color);
return SVGPaintDescription(color);
......@@ -141,7 +117,7 @@ static SVGPaintDescription RequestPaint(const LayoutObject& object,
if (!uri_resource) {
// The fallback is 'none'. (SVG2 say 'none' is implied when no fallback is
// specified.)
if (paint_type == SVG_PAINTTYPE_URI_NONE || !has_color)
if (!paint.HasFallbackColor() || !has_color)
return SVGPaintDescription();
return SVGPaintDescription(color);
......
......@@ -123,19 +123,6 @@ static inline AtomicString TargetReferenceFromResource(SVGElement& element) {
target, element.GetTreeScope());
}
static inline bool SvgPaintTypeHasURL(SVGPaintType paint_type) {
switch (paint_type) {
case SVG_PAINTTYPE_URI_NONE:
case SVG_PAINTTYPE_URI_CURRENTCOLOR:
case SVG_PAINTTYPE_URI_RGBCOLOR:
case SVG_PAINTTYPE_URI:
return true;
default:
break;
}
return false;
}
namespace {
template <typename ContainerType>
......@@ -253,17 +240,17 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources(
}
if (FillAndStrokeTags().Contains(tag_name)) {
if (style.HasFill() && SvgPaintTypeHasURL(style.FillPaintType())) {
if (style.HasFill() && style.FillPaint().HasUrl()) {
AtomicString id = SVGURIReference::FragmentIdentifierFromIRIString(
style.FillPaintUri(), tree_scope);
style.FillPaint().GetUrl(), tree_scope);
EnsureResources(resources).SetFill(
AttachToResource<LayoutSVGResourcePaintServer>(tree_scope_resources,
id, element));
}
if (style.HasStroke() && SvgPaintTypeHasURL(style.StrokePaintType())) {
if (style.HasStroke() && style.StrokePaint().HasUrl()) {
AtomicString id = SVGURIReference::FragmentIdentifierFromIRIString(
style.StrokePaintUri(), tree_scope);
style.StrokePaint().GetUrl(), tree_scope);
EnsureResources(resources).SetStroke(
AttachToResource<LayoutSVGResourcePaintServer>(tree_scope_resources,
id, element));
......
......@@ -980,12 +980,6 @@ class ComputedStyle : public ComputedStyleBase,
float FillOpacity() const { return SvgStyle().FillOpacity(); }
void SetFillOpacity(float f) { AccessSVGStyle().SetFillOpacity(f); }
// Fill utiltiy functions.
const SVGPaintType& FillPaintType() const {
return SvgStyle().FillPaintType();
}
Color FillPaintColor() const { return SvgStyle().FillPaintColor(); }
// stop-color
void SetStopColor(const Color& c) { AccessSVGStyle().SetStopColor(c); }
......@@ -1005,12 +999,6 @@ class ComputedStyle : public ComputedStyleBase,
float StopOpacity() const { return SvgStyle().StopOpacity(); }
void SetStopOpacity(float f) { AccessSVGStyle().SetStopOpacity(f); }
// stroke
const SVGPaintType& StrokePaintType() const {
return SvgStyle().StrokePaintType();
}
Color StrokePaintColor() const { return SvgStyle().StrokePaintColor(); }
// stroke-dasharray
SVGDashArray* StrokeDashArray() const { return SvgStyle().StrokeDashArray(); }
void SetStrokeDashArray(scoped_refptr<SVGDashArray> array) {
......
......@@ -170,18 +170,11 @@ bool SVGComputedStyle::DiffNeedsLayoutAndPaintInvalidation(
// need to be recalculated.
if (stroke.Get() != other->stroke.Get()) {
if (stroke->width != other->stroke->width ||
stroke->paint_type != other->stroke->paint_type ||
stroke->paint_color != other->stroke->paint_color ||
stroke->paint_uri != other->stroke->paint_uri ||
stroke->paint != other->stroke->paint ||
stroke->miter_limit != other->stroke->miter_limit ||
*stroke->dash_array != *other->stroke->dash_array ||
stroke->dash_offset != other->stroke->dash_offset ||
stroke->visited_link_paint_color !=
other->stroke->visited_link_paint_color ||
stroke->visited_link_paint_uri !=
other->stroke->visited_link_paint_uri ||
stroke->visited_link_paint_type !=
other->stroke->visited_link_paint_type)
stroke->visited_link_paint != other->stroke->visited_link_paint)
return true;
}
......@@ -208,9 +201,7 @@ bool SVGComputedStyle::DiffNeedsPaintInvalidation(
// If fill changes, we just need to issue paint invalidations. Fill boundaries
// are not influenced by this, only by the Path, that LayoutSVGPath contains.
if (fill.Get() != other->fill.Get()) {
if (fill->paint_type != other->fill->paint_type ||
fill->paint_color != other->fill->paint_color ||
fill->paint_uri != other->fill->paint_uri ||
if (fill->paint != other->fill->paint ||
fill->opacity != other->fill->opacity)
return true;
}
......
......@@ -78,13 +78,9 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
static EShapeRendering InitialShapeRendering() { return SR_AUTO; }
static ETextAnchor InitialTextAnchor() { return TA_START; }
static float InitialFillOpacity() { return 1; }
static SVGPaintType InitialFillPaintType() { return SVG_PAINTTYPE_RGBCOLOR; }
static Color InitialFillPaintColor() { return Color::kBlack; }
static String InitialFillPaintUri() { return String(); }
static SVGPaint InitialFillPaint() { return SVGPaint(Color::kBlack); }
static float InitialStrokeOpacity() { return 1; }
static SVGPaintType InitialStrokePaintType() { return SVG_PAINTTYPE_NONE; }
static Color InitialStrokePaintColor() { return Color(); }
static String InitialStrokePaintUri() { return String(); }
static SVGPaint InitialStrokePaint() { return SVGPaint(); }
static scoped_refptr<SVGDashArray> InitialStrokeDashArray();
static Length InitialStrokeDashOffset() { return Length(kFixed); }
static float InitialStrokeMiterLimit() { return 4; }
......@@ -187,27 +183,14 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
fill.Access()->opacity = obj;
}
void SetFillPaint(SVGPaintType type,
const Color& color,
const String& uri,
bool apply_to_regular_style = true,
bool apply_to_visited_link_style = false) {
if (apply_to_regular_style) {
if (!(fill->paint_type == type))
fill.Access()->paint_type = type;
if (!(fill->paint_color == color))
fill.Access()->paint_color = color;
if (!(fill->paint_uri == uri))
fill.Access()->paint_uri = uri;
}
if (apply_to_visited_link_style) {
if (!(fill->visited_link_paint_type == type))
fill.Access()->visited_link_paint_type = type;
if (!(fill->visited_link_paint_color == color))
fill.Access()->visited_link_paint_color = color;
if (!(fill->visited_link_paint_uri == uri))
fill.Access()->visited_link_paint_uri = uri;
}
void SetFillPaint(const SVGPaint& paint) {
if (!(fill->paint == paint))
fill.Access()->paint = paint;
}
void SetVisitedLinkFillPaint(const SVGPaint& paint) {
if (!(fill->visited_link_paint == paint))
fill.Access()->visited_link_paint = paint;
}
void SetStrokeOpacity(float obj) {
......@@ -215,27 +198,14 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
stroke.Access()->opacity = obj;
}
void SetStrokePaint(SVGPaintType type,
const Color& color,
const String& uri,
bool apply_to_regular_style = true,
bool apply_to_visited_link_style = false) {
if (apply_to_regular_style) {
if (!(stroke->paint_type == type))
stroke.Access()->paint_type = type;
if (!(stroke->paint_color == color))
stroke.Access()->paint_color = color;
if (!(stroke->paint_uri == uri))
stroke.Access()->paint_uri = uri;
}
if (apply_to_visited_link_style) {
if (!(stroke->visited_link_paint_type == type))
stroke.Access()->visited_link_paint_type = type;
if (!(stroke->visited_link_paint_color == color))
stroke.Access()->visited_link_paint_color = color;
if (!(stroke->visited_link_paint_uri == uri))
stroke.Access()->visited_link_paint_uri = uri;
}
void SetStrokePaint(const SVGPaint& paint) {
if (!(stroke->paint == paint))
stroke.Access()->paint = paint;
}
void SetVisitedLinkStrokePaint(const SVGPaint& paint) {
if (!(stroke->visited_link_paint == paint))
stroke.Access()->visited_link_paint = paint;
}
void SetStrokeDashArray(scoped_refptr<SVGDashArray> dash_array) {
......@@ -348,13 +318,9 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
return (ETextAnchor)svg_inherited_flags.text_anchor;
}
float FillOpacity() const { return fill->opacity; }
const SVGPaintType& FillPaintType() const { return fill->paint_type; }
const Color& FillPaintColor() const { return fill->paint_color; }
const String& FillPaintUri() const { return fill->paint_uri; }
const SVGPaint& FillPaint() const { return fill->paint; }
float StrokeOpacity() const { return stroke->opacity; }
const SVGPaintType& StrokePaintType() const { return stroke->paint_type; }
const Color& StrokePaintColor() const { return stroke->paint_color; }
const String& StrokePaintUri() const { return stroke->paint_uri; }
const SVGPaint& StrokePaint() const { return stroke->paint; }
SVGDashArray* StrokeDashArray() const { return stroke->dash_array.get(); }
float StrokeMiterLimit() const { return stroke->miter_limit; }
const UnzoomedLength& StrokeWidth() const { return stroke->width; }
......@@ -393,37 +359,21 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
}
EPaintOrderType PaintOrderType(unsigned index) const;
const SVGPaintType& VisitedLinkFillPaintType() const {
return fill->visited_link_paint_type;
}
const Color& VisitedLinkFillPaintColor() const {
return fill->visited_link_paint_color;
}
const String& VisitedLinkFillPaintUri() const {
return fill->visited_link_paint_uri;
}
const SVGPaintType& VisitedLinkStrokePaintType() const {
return stroke->visited_link_paint_type;
}
const Color& VisitedLinkStrokePaintColor() const {
return stroke->visited_link_paint_color;
const SVGPaint& VisitedLinkFillPaint() const {
return fill->visited_link_paint;
}
const String& VisitedLinkStrokePaintUri() const {
return stroke->visited_link_paint_uri;
const SVGPaint& VisitedLinkStrokePaint() const {
return stroke->visited_link_paint;
}
bool IsFillColorCurrentColor() const {
return FillPaintType() == SVG_PAINTTYPE_CURRENTCOLOR ||
VisitedLinkFillPaintType() == SVG_PAINTTYPE_CURRENTCOLOR ||
FillPaintType() == SVG_PAINTTYPE_URI_CURRENTCOLOR ||
VisitedLinkFillPaintType() == SVG_PAINTTYPE_URI_CURRENTCOLOR;
return FillPaint().HasCurrentColor() ||
VisitedLinkFillPaint().HasCurrentColor();
}
bool IsStrokeColorCurrentColor() const {
return StrokePaintType() == SVG_PAINTTYPE_CURRENTCOLOR ||
VisitedLinkStrokePaintType() == SVG_PAINTTYPE_CURRENTCOLOR ||
StrokePaintType() == SVG_PAINTTYPE_URI_CURRENTCOLOR ||
VisitedLinkStrokePaintType() == SVG_PAINTTYPE_URI_CURRENTCOLOR;
return StrokePaint().HasCurrentColor() ||
VisitedLinkStrokePaint().HasCurrentColor();
}
// convenience
......@@ -432,11 +382,11 @@ class SVGComputedStyle : public RefCounted<SVGComputedStyle> {
return !MarkerStartResource().IsEmpty() || !MarkerMidResource().IsEmpty() ||
!MarkerEndResource().IsEmpty();
}
bool HasStroke() const { return StrokePaintType() != SVG_PAINTTYPE_NONE; }
bool HasStroke() const { return !StrokePaint().IsNone(); }
bool HasVisibleStroke() const {
return HasStroke() && !StrokeWidth().IsZero();
}
bool HasFill() const { return FillPaintType() != SVG_PAINTTYPE_NONE; }
bool HasFill() const { return !FillPaint().IsNone(); }
protected:
// inherit
......
......@@ -32,31 +32,24 @@
namespace blink {
bool SVGPaint::operator==(const SVGPaint& other) const {
return type == other.type && color == other.color && url == other.url;
}
StyleFillData::StyleFillData()
: opacity(SVGComputedStyle::InitialFillOpacity()),
paint_type(SVGComputedStyle::InitialFillPaintType()),
paint_color(SVGComputedStyle::InitialFillPaintColor()),
paint_uri(SVGComputedStyle::InitialFillPaintUri()),
visited_link_paint_type(SVGComputedStyle::InitialFillPaintType()),
visited_link_paint_color(SVGComputedStyle::InitialFillPaintColor()),
visited_link_paint_uri(SVGComputedStyle::InitialFillPaintUri()) {}
paint(SVGComputedStyle::InitialFillPaint()),
visited_link_paint(SVGComputedStyle::InitialFillPaint()) {}
StyleFillData::StyleFillData(const StyleFillData& other)
: RefCounted<StyleFillData>(),
opacity(other.opacity),
paint_type(other.paint_type),
paint_color(other.paint_color),
paint_uri(other.paint_uri),
visited_link_paint_type(other.visited_link_paint_type),
visited_link_paint_color(other.visited_link_paint_color),
visited_link_paint_uri(other.visited_link_paint_uri) {}
paint(other.paint),
visited_link_paint(other.visited_link_paint) {}
bool StyleFillData::operator==(const StyleFillData& other) const {
return opacity == other.opacity && paint_type == other.paint_type &&
paint_color == other.paint_color && paint_uri == other.paint_uri &&
visited_link_paint_type == other.visited_link_paint_type &&
visited_link_paint_color == other.visited_link_paint_color &&
visited_link_paint_uri == other.visited_link_paint_uri;
return opacity == other.opacity && paint == other.paint &&
visited_link_paint == other.visited_link_paint;
}
StyleStrokeData::StyleStrokeData()
......@@ -65,12 +58,8 @@ StyleStrokeData::StyleStrokeData()
width(SVGComputedStyle::InitialStrokeWidth()),
dash_offset(SVGComputedStyle::InitialStrokeDashOffset()),
dash_array(SVGComputedStyle::InitialStrokeDashArray()),
paint_type(SVGComputedStyle::InitialStrokePaintType()),
paint_color(SVGComputedStyle::InitialStrokePaintColor()),
paint_uri(SVGComputedStyle::InitialStrokePaintUri()),
visited_link_paint_type(SVGComputedStyle::InitialStrokePaintType()),
visited_link_paint_color(SVGComputedStyle::InitialStrokePaintColor()),
visited_link_paint_uri(SVGComputedStyle::InitialStrokePaintUri()) {}
paint(SVGComputedStyle::InitialStrokePaint()),
visited_link_paint(SVGComputedStyle::InitialStrokePaint()) {}
StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
: RefCounted<StyleStrokeData>(),
......@@ -79,21 +68,14 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
width(other.width),
dash_offset(other.dash_offset),
dash_array(other.dash_array),
paint_type(other.paint_type),
paint_color(other.paint_color),
paint_uri(other.paint_uri),
visited_link_paint_type(other.visited_link_paint_type),
visited_link_paint_color(other.visited_link_paint_color),
visited_link_paint_uri(other.visited_link_paint_uri) {}
paint(other.paint),
visited_link_paint(other.visited_link_paint) {}
bool StyleStrokeData::operator==(const StyleStrokeData& other) const {
return width == other.width && opacity == other.opacity &&
miter_limit == other.miter_limit && dash_offset == other.dash_offset &&
*dash_array == *other.dash_array && paint_type == other.paint_type &&
paint_color == other.paint_color && paint_uri == other.paint_uri &&
visited_link_paint_type == other.visited_link_paint_type &&
visited_link_paint_color == other.visited_link_paint_color &&
visited_link_paint_uri == other.visited_link_paint_uri;
*dash_array == *other.dash_array && paint == other.paint &&
visited_link_paint == other.visited_link_paint;
}
StyleStopData::StyleStopData()
......
......@@ -119,6 +119,41 @@ enum EPaintOrder {
kPaintOrderMarkersStrokeFill = 6
};
struct SVGPaint {
SVGPaint() : type(SVG_PAINTTYPE_NONE) {}
SVGPaint(Color color) : type(SVG_PAINTTYPE_RGBCOLOR), color(color) {}
CORE_EXPORT bool operator==(const SVGPaint&) const;
bool operator!=(const SVGPaint& other) const { return !(*this == other); }
bool IsNone() const { return type == SVG_PAINTTYPE_NONE; }
bool IsColor() const {
return type == SVG_PAINTTYPE_RGBCOLOR || type == SVG_PAINTTYPE_CURRENTCOLOR;
}
// Used by CSSPropertyEquality::PropertiesEqual.
bool EqualTypeOrColor(const SVGPaint& other) const {
return type == other.type &&
(type != SVG_PAINTTYPE_RGBCOLOR || color == other.color);
}
bool HasFallbackColor() const {
return type == SVG_PAINTTYPE_URI_CURRENTCOLOR ||
type == SVG_PAINTTYPE_URI_RGBCOLOR;
}
bool HasColor() const { return IsColor() || HasFallbackColor(); }
bool HasUrl() const { return type >= SVG_PAINTTYPE_URI_NONE; }
bool HasCurrentColor() const {
return type == SVG_PAINTTYPE_CURRENTCOLOR ||
type == SVG_PAINTTYPE_URI_CURRENTCOLOR;
}
const Color& GetColor() const { return color; }
const String& GetUrl() const { return url; }
SVGPaintType type;
Color color;
String url;
};
// Inherited/Non-Inherited Style Datastructures
class StyleFillData : public RefCounted<StyleFillData> {
public:
......@@ -135,12 +170,8 @@ class StyleFillData : public RefCounted<StyleFillData> {
}
float opacity;
SVGPaintType paint_type;
Color paint_color;
String paint_uri;
SVGPaintType visited_link_paint_type;
Color visited_link_paint_color;
String visited_link_paint_uri;
SVGPaint paint;
SVGPaint visited_link_paint;
private:
StyleFillData();
......@@ -190,12 +221,8 @@ class CORE_EXPORT StyleStrokeData : public RefCounted<StyleStrokeData> {
Length dash_offset;
scoped_refptr<SVGDashArray> dash_array;
SVGPaintType paint_type;
Color paint_color;
String paint_uri;
SVGPaintType visited_link_paint_type;
Color visited_link_paint_color;
String visited_link_paint_uri;
SVGPaint paint;
SVGPaint visited_link_paint;
private:
StyleStrokeData();
......
......@@ -41,30 +41,12 @@ TEST(SVGComputedStyleTest, StrokeStyleShouldCompareValue) {
TEST_STYLE_VALUE_NO_DIFF(Length, StrokeDashOffset);
TEST_STYLE_REFPTR_VALUE_NO_DIFF(SVGDashArray, StrokeDashArray);
TEST_STYLE_VALUE_NO_DIFF(SVGPaint, StrokePaint);
{
scoped_refptr<SVGComputedStyle> svg1 = SVGComputedStyle::Create();
scoped_refptr<SVGComputedStyle> svg2 = SVGComputedStyle::Create();
svg1->SetStrokePaint(SVGComputedStyle::InitialStrokePaintType(),
SVGComputedStyle::InitialStrokePaintColor(),
SVGComputedStyle::InitialStrokePaintUri(), true,
false);
svg2->SetStrokePaint(SVGComputedStyle::InitialStrokePaintType(),
SVGComputedStyle::InitialStrokePaintColor(),
SVGComputedStyle::InitialStrokePaintUri(), true,
false);
EXPECT_FALSE(svg1->Diff(svg2.get()).HasDifference());
}
{
scoped_refptr<SVGComputedStyle> svg1 = SVGComputedStyle::Create();
scoped_refptr<SVGComputedStyle> svg2 = SVGComputedStyle::Create();
svg1->SetStrokePaint(SVGComputedStyle::InitialStrokePaintType(),
SVGComputedStyle::InitialStrokePaintColor(),
SVGComputedStyle::InitialStrokePaintUri(), false,
true);
svg2->SetStrokePaint(SVGComputedStyle::InitialStrokePaintType(),
SVGComputedStyle::InitialStrokePaintColor(),
SVGComputedStyle::InitialStrokePaintUri(), false,
true);
svg1->SetVisitedLinkStrokePaint(SVGComputedStyle::InitialStrokePaint());
svg2->SetVisitedLinkStrokePaint(SVGComputedStyle::InitialStrokePaint());
EXPECT_FALSE(svg1->Diff(svg2.get()).HasDifference());
}
}
......
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