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

Use LayoutUnit for SVGImage's "container size"

Impedance-wise this is slightly better since we generally start out as
float, and thus we won't lose as much precision. This means that viewBox
transform computations and similar will be more accurate.

Make the (recently added) test
wpt/svg/embedded/image-fractional-width-vertical-fidelity.svg slightly more
conservative.

Bug: 812239
Change-Id: I231f596f854ef37ae4e0d2dc3b705e546ee187d4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1969672Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#725556}
parent 18f4fa42
......@@ -130,7 +130,7 @@ LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalWidth(
// (border-image/background-image/<html:img>/...) we're forced to resize to a
// specific size.
if (!container_size_.IsEmpty())
return LayoutUnit(container_size_.Width());
return container_size_.Width();
if (IsEmbeddedThroughFrameContainingSVGDocument())
return ContainingBlock()->AvailableLogicalWidth();
......@@ -144,7 +144,7 @@ LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalHeight(
// (border-image/background-image/<html:img>/...) we're forced to resize to a
// specific size.
if (!container_size_.IsEmpty())
return LayoutUnit(container_size_.Height());
return container_size_.Height();
if (IsEmbeddedThroughFrameContainingSVGDocument())
return ContainingBlock()->AvailableLogicalHeight(
......
......@@ -65,8 +65,8 @@ class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
needs_boundaries_or_transform_update_ = true;
}
IntSize ContainerSize() const { return container_size_; }
void SetContainerSize(const IntSize& container_size) {
LayoutSize ContainerSize() const { return container_size_; }
void SetContainerSize(const LayoutSize& container_size) {
// SVGImage::draw() does a view layout prior to painting,
// and we need that layout to know of the new size otherwise
// the layout may be incorrectly using the old size.
......@@ -162,7 +162,7 @@ class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
PositionWithAffinity PositionForPoint(const PhysicalOffset&) const final;
LayoutObjectChildList children_;
IntSize container_size_;
LayoutSize container_size_;
FloatRect object_bounding_box_;
bool object_bounding_box_valid_;
FloatRect stroke_bounding_box_;
......
......@@ -183,18 +183,18 @@ static SVGSVGElement* SvgRootElement(Page* page) {
return frame->GetDocument()->AccessSVGExtensions().rootElement();
}
IntSize SVGImage::ContainerSize() const {
LayoutSize SVGImage::ContainerSize() const {
SVGSVGElement* root_element = SvgRootElement(page_.Get());
if (!root_element)
return IntSize();
return LayoutSize();
LayoutSVGRoot* layout_object =
ToLayoutSVGRoot(root_element->GetLayoutObject());
if (!layout_object)
return IntSize();
return LayoutSize();
// If a container size is available it has precedence.
IntSize container_size = layout_object->ContainerSize();
LayoutSize container_size = layout_object->ContainerSize();
if (!container_size.IsEmpty())
return container_size;
......@@ -205,6 +205,10 @@ IntSize SVGImage::ContainerSize() const {
return intrinsic_size_;
}
IntSize SVGImage::Size() const {
return RoundedIntSize(intrinsic_size_);
}
static float ResolveWidthForRatio(float height,
const FloatSize& intrinsic_ratio) {
return height * intrinsic_ratio.Width() / intrinsic_ratio.Height();
......@@ -303,7 +307,7 @@ void SVGImage::ForContainer(const FloatSize& container_size, Func&& func) {
// re-laying out the image.
ImageObserverDisabler image_observer_disabler(this);
IntSize rounded_container_size = RoundedIntSize(container_size);
LayoutSize rounded_container_size = RoundedLayoutSize(container_size);
if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) {
if (LayoutSVGRoot* layout_object =
......@@ -448,12 +452,11 @@ static bool DrawNeedsLayer(const PaintFlags& flags) {
bool SVGImage::ApplyShaderInternal(PaintFlags& flags,
const SkMatrix& local_matrix,
const KURL& url) {
const IntSize size(ContainerSize());
const FloatSize size(ContainerSize());
if (size.IsEmpty())
return false;
IntRect bounds(IntPoint(), size);
FloatRect bounds(FloatPoint(), size);
flags.setShader(PaintShader::MakePaintRecord(
PaintRecordForCurrentFrame(url), bounds, SkTileMode::kRepeat,
SkTileMode::kRepeat, &local_matrix));
......@@ -505,8 +508,9 @@ void SVGImage::Draw(
sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const KURL& url) {
DCHECK(page_);
LocalFrameView* view = To<LocalFrame>(page_->MainFrame())->View();
view->Resize(ContainerSize());
page_->GetVisualViewport().SetSize(ContainerSize());
IntSize rounded_container_size = RoundedIntSize(ContainerSize());
view->Resize(rounded_container_size);
page_->GetVisualViewport().SetSize(rounded_container_size);
// Always call processUrlFragment, even if the url is empty, because
// there may have been a previous url/fragment that needs to be reset.
......@@ -816,7 +820,7 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
frame->GetDocument()->UpdateStyleAndLayoutTree();
// Set the concrete object size before a container size is available.
intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize(
intrinsic_size_ = RoundedLayoutSize(ConcreteObjectSize(FloatSize(
LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight)));
DCHECK(page_);
......
......@@ -29,6 +29,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
......@@ -66,7 +67,7 @@ class CORE_EXPORT SVGImage final : public Image {
static bool IsInSVGImage(const Node*);
bool IsSVGImage() const override { return true; }
IntSize Size() const override { return intrinsic_size_; }
IntSize Size() const override;
void CheckLoaded() const;
bool CurrentFrameHasSingleSecurityOrigin() const override;
......@@ -144,7 +145,7 @@ class CORE_EXPORT SVGImage final : public Image {
String FilenameExtension() const override;
IntSize ContainerSize() const;
LayoutSize ContainerSize() const;
SizeAvailability DataChanged(bool all_data_received) override;
......@@ -227,7 +228,7 @@ class CORE_EXPORT SVGImage final : public Image {
// belong to multiple containers so the final image size can't be known in
// SVGImage. SVGImageForContainer carries the final image size, also called
// the "concrete object size". For more, see: SVGImageForContainer.h
IntSize intrinsic_size_;
LayoutSize intrinsic_size_;
bool has_pending_timeline_rewind_;
enum LoadState {
......
......@@ -2,10 +2,11 @@
<title>Vertical fidelity of &#x3c;image&#x3e; element with fractional width</title>
<h:link rel="help" href="https://svgwg.org/svg2-draft/embedded.html#ImageElement"/>
<h:link rel="match" href="reference/green-rect-100x100.svg"/>
<rect width="100" height="100" fill="red"/>
<rect x="95" width="5" height="100" fill="green"/>
<rect width="95" height="100" fill="red"/>
<g clip-path="url(#c)">
<clipPath id="c">
<rect width="100" height="100"/>
<rect width="95" height="100"/>
</clipPath>
<image href="data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='xMinYMin'%3e
%3crect width='100' height='100' fill='green'/%3e%3c/svg%3e"
......
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