Commit 6e91cad5 authored by Luna Lu's avatar Luna Lu Committed by Commit Bot

Add intrinsicSize attribute to SVGImageElement

Design doc: https://docs.google.com/document/d/1yh_-ayeaFV0EjuR51U641zbrPAB0Baqj6UrC9bT9iqQ/edit#heading=h.y7amr11fn0tb

This CL implements "intrinsicSize" attribute to SVGImageElement. This
attribute has been added to HTMLImageElement and HTMLVideoElement.
The value of "intrinsicSize" overrides the intrinsic size:

1. When no width and height is specified, the value of "intrinsicSize"
specifies the <svg:image> element's layout size.
2. When one dimension is specified, the value of "intrinsicSize" is
used as an aspect ratio to determine the other dimension.
3. If both width and height are specified, "intrinsicSize" has no
effect.

Bug: 874629
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I9023d6cf7a818c983155efc12505f1d6fd18de43
Reviewed-on: https://chromium-review.googlesource.com/1210544Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Commit-Queue: Luna Lu <loonybear@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590065}
parent c27c9d9d
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" width="32" height="32"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" width="300" height="150"/>
</svg>
<svg width=400 height=400>
<image href="/feature-policy/experimental-features/resources/image.png" width="300" height="150"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" width="300" height="150"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" height="50" width="100"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" width="100" height="100"/>
</svg>
</body>
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="match" href="intrinsicsize-svg-image-ref.html">
<meta name="assert" content="test">
<body>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" intrinsicsize="300x150"/>
</svg>
<svg width=400 height=400>
<image href="/feature-policy/experimental-features/resources/image.png" intrinsicsize="300x150"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" intrinsicsize="300x150" width="300"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" intrinsicsize="300x150" height="50"/>
</svg>
<svg width=200 height=200>
<image href="/feature-policy/experimental-features/resources/image.png" intrinsicsize="300x150" width="100" height="100"/>
</svg>
</body>
...@@ -1879,6 +1879,7 @@ svg element image ...@@ -1879,6 +1879,7 @@ svg element image
property getScreenCTM property getScreenCTM
property height property height
property href property href
property intrinsicSize
property nearestViewportElement property nearestViewportElement
property preserveAspectRatio property preserveAspectRatio
property requiredExtensions property requiredExtensions
......
...@@ -65,13 +65,25 @@ static float ResolveHeightForRatio(float width, ...@@ -65,13 +65,25 @@ static float ResolveHeightForRatio(float width,
return width * intrinsic_ratio.Height() / intrinsic_ratio.Width(); return width * intrinsic_ratio.Height() / intrinsic_ratio.Width();
} }
IntSize LayoutSVGImage::GetOverriddenIntrinsicSize() const {
if (auto* svg_image = ToSVGImageElementOrNull(GetElement())) {
if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
return svg_image->GetOverriddenIntrinsicSize();
}
return IntSize();
}
FloatSize LayoutSVGImage::CalculateObjectSize() const { FloatSize LayoutSVGImage::CalculateObjectSize() const {
FloatSize intrinsic_size = FloatSize(GetOverriddenIntrinsicSize());
ImageResourceContent* cached_image = image_resource_->CachedImage(); ImageResourceContent* cached_image = image_resource_->CachedImage();
if (!cached_image || cached_image->ErrorOccurred() || if (intrinsic_size.IsEmpty()) {
!cached_image->IsSizeAvailable()) if (!cached_image || cached_image->ErrorOccurred() ||
return object_bounding_box_.Size(); !cached_image->IsSizeAvailable())
return object_bounding_box_.Size();
intrinsic_size = FloatSize(cached_image->GetImage()->Size());
}
FloatSize intrinsic_size = FloatSize(cached_image->GetImage()->Size());
if (StyleRef().Width().IsAuto() && StyleRef().Height().IsAuto()) if (StyleRef().Width().IsAuto() && StyleRef().Height().IsAuto())
return intrinsic_size; return intrinsic_size;
......
...@@ -76,6 +76,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject { ...@@ -76,6 +76,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject {
} }
FloatSize CalculateObjectSize() const; FloatSize CalculateObjectSize() const;
IntSize GetOverriddenIntrinsicSize() const;
bool needs_boundaries_update_ : 1; bool needs_boundaries_update_ : 1;
bool needs_transform_update_ : 1; bool needs_transform_update_ : 1;
......
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
"in", "in",
"in2", "in2",
"intercept", "intercept",
"intrinsicsize",
"k", "k",
"k1", "k1",
"k2", "k2",
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css_property_names.h" #include "third_party/blink/renderer/core/css_property_names.h"
#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/layout_image_resource.h" #include "third_party/blink/renderer/core/layout/layout_image_resource.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
#include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/core/svg_names.h"
...@@ -160,6 +162,22 @@ void SVGImageElement::ParseAttribute( ...@@ -160,6 +162,22 @@ void SVGImageElement::ParseAttribute(
if (params.name == SVGNames::decodingAttr) { if (params.name == SVGNames::decodingAttr) {
UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute); UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute);
decoding_mode_ = ParseImageDecodingMode(params.new_value); decoding_mode_ = ParseImageDecodingMode(params.new_value);
} else if (params.name == SVGNames::intrinsicsizeAttr &&
RuntimeEnabledFeatures::
ExperimentalProductivityFeaturesEnabled()) {
String message;
bool intrinsic_size_changed =
MediaElementParserHelpers::ParseIntrinsicSizeAttribute(
params.new_value, &overridden_intrinsic_size_, &message);
if (!message.IsEmpty()) {
GetDocument().AddConsoleMessage(ConsoleMessage::Create(
kOtherMessageSource, kWarningMessageLevel, message));
}
if (intrinsic_size_changed) {
if (LayoutSVGImage* layout_obj = ToLayoutSVGImage(GetLayoutObject()))
MarkForLayoutAndParentResourceInvalidation(*layout_obj);
}
} else { } else {
SVGElement::ParseAttribute(params); SVGElement::ParseAttribute(params);
} }
......
...@@ -54,6 +54,10 @@ class CORE_EXPORT SVGImageElement final ...@@ -54,6 +54,10 @@ class CORE_EXPORT SVGImageElement final
return preserve_aspect_ratio_.Get(); return preserve_aspect_ratio_.Get();
} }
IntSize GetOverriddenIntrinsicSize() const {
return overridden_intrinsic_size_;
}
bool HasPendingActivity() const final { bool HasPendingActivity() const final {
return GetImageLoader().HasPendingActivity(); return GetImageLoader().HasPendingActivity();
} }
...@@ -93,6 +97,8 @@ class CORE_EXPORT SVGImageElement final ...@@ -93,6 +97,8 @@ class CORE_EXPORT SVGImageElement final
void DidMoveToNewDocument(Document& old_document) override; void DidMoveToNewDocument(Document& old_document) override;
SVGImageLoader& GetImageLoader() const override { return *image_loader_; } SVGImageLoader& GetImageLoader() const override { return *image_loader_; }
IntSize overridden_intrinsic_size_;
Member<SVGAnimatedLength> x_; Member<SVGAnimatedLength> x_;
Member<SVGAnimatedLength> y_; Member<SVGAnimatedLength> y_;
Member<SVGAnimatedLength> width_; Member<SVGAnimatedLength> width_;
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
[MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedLength height; [MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedLength height;
[MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; [MeasureAs=SVG1DOMImageElement] readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
[CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding; [CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
// https://github.com/ojanvafai/intrinsicsize-attribute/blob/master/README.md
[RuntimeEnabled=ExperimentalProductivityFeatures, CEReactions, Reflect] attribute DOMString intrinsicSize;
[CallWith=ScriptState, RaisesException] Promise decode(); [CallWith=ScriptState, RaisesException] Promise decode();
}; };
......
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