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

Fix transform-box handling for <svg:image>

The transform for <svg:image> was not being updated properly when the
reference box was changed.

Bug: 1007146
Change-Id: I39e73105e4a2d284afd1588e38eb8ff90e45c6f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1824271Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#700133}
parent 88843393
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h" #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/core/layout/svg/transform_helper.h"
#include "third_party/blink/renderer/core/layout/svg/transformed_hit_test_location.h" #include "third_party/blink/renderer/core/layout/svg/transformed_hit_test_location.h"
#include "third_party/blink/renderer/core/paint/image_element_timing.h" #include "third_party/blink/renderer/core/paint/image_element_timing.h"
#include "third_party/blink/renderer/core/paint/svg_image_painter.h" #include "third_party/blink/renderer/core/paint/svg_image_painter.h"
...@@ -47,12 +48,20 @@ LayoutSVGImage::LayoutSVGImage(SVGImageElement* impl) ...@@ -47,12 +48,20 @@ LayoutSVGImage::LayoutSVGImage(SVGImageElement* impl)
: LayoutSVGModelObject(impl), : LayoutSVGModelObject(impl),
needs_boundaries_update_(true), needs_boundaries_update_(true),
needs_transform_update_(true), needs_transform_update_(true),
transform_uses_reference_box_(false),
image_resource_(MakeGarbageCollected<LayoutImageResource>()) { image_resource_(MakeGarbageCollected<LayoutImageResource>()) {
image_resource_->Initialize(this); image_resource_->Initialize(this);
} }
LayoutSVGImage::~LayoutSVGImage() = default; LayoutSVGImage::~LayoutSVGImage() = default;
void LayoutSVGImage::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
transform_uses_reference_box_ =
TransformHelper::DependsOnReferenceBox(StyleRef());
LayoutSVGModelObject::StyleDidChange(diff, old_style);
}
void LayoutSVGImage::WillBeDestroyed() { void LayoutSVGImage::WillBeDestroyed() {
image_resource_->Shutdown(); image_resource_->Shutdown();
...@@ -132,17 +141,11 @@ void LayoutSVGImage::UpdateLayout() { ...@@ -132,17 +141,11 @@ void LayoutSVGImage::UpdateLayout() {
if (EverHadLayout() && SelfNeedsLayout()) if (EverHadLayout() && SelfNeedsLayout())
SVGResourcesCache::ClientLayoutChanged(*this); SVGResourcesCache::ClientLayoutChanged(*this);
UpdateBoundingBox(); FloatPoint old_bbox_location = object_bounding_box_.Location();
bool bbox_changed = UpdateBoundingBox() ||
old_bbox_location != object_bounding_box_.Location();
bool update_parent_boundaries = false; bool update_parent_boundaries = false;
if (needs_transform_update_) {
local_transform_ =
ToSVGImageElement(GetElement())
->CalculateTransform(SVGElement::kIncludeMotionTransform);
needs_transform_update_ = false;
update_parent_boundaries = true;
}
if (needs_boundaries_update_) { if (needs_boundaries_update_) {
local_visual_rect_ = object_bounding_box_; local_visual_rect_ = object_bounding_box_;
SVGLayoutSupport::AdjustVisualRectWithResources(*this, object_bounding_box_, SVGLayoutSupport::AdjustVisualRectWithResources(*this, object_bounding_box_,
...@@ -151,6 +154,18 @@ void LayoutSVGImage::UpdateLayout() { ...@@ -151,6 +154,18 @@ void LayoutSVGImage::UpdateLayout() {
update_parent_boundaries = true; update_parent_boundaries = true;
} }
if (!needs_transform_update_ && transform_uses_reference_box_) {
needs_transform_update_ = CheckForImplicitTransformChange(bbox_changed);
if (needs_transform_update_)
SetNeedsPaintPropertyUpdate();
}
if (needs_transform_update_) {
local_transform_ = CalculateLocalTransform();
needs_transform_update_ = false;
update_parent_boundaries = true;
}
// If our bounds changed, notify the parents. // If our bounds changed, notify the parents.
if (update_parent_boundaries) if (update_parent_boundaries)
LayoutSVGModelObject::SetNeedsBoundariesUpdate(); LayoutSVGModelObject::SetNeedsBoundariesUpdate();
......
...@@ -57,6 +57,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject { ...@@ -57,6 +57,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject {
const char* GetName() const override { return "LayoutSVGImage"; } const char* GetName() const override { return "LayoutSVGImage"; }
protected: protected:
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void WillBeDestroyed() override; void WillBeDestroyed() override;
private: private:
...@@ -83,6 +84,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject { ...@@ -83,6 +84,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject {
bool needs_boundaries_update_ : 1; bool needs_boundaries_update_ : 1;
bool needs_transform_update_ : 1; bool needs_transform_update_ : 1;
bool transform_uses_reference_box_ : 1;
AffineTransform local_transform_; AffineTransform local_transform_;
FloatRect object_bounding_box_; FloatRect object_bounding_box_;
Persistent<LayoutImageResource> image_resource_; Persistent<LayoutImageResource> image_resource_;
......
<!DOCTYPE html>
<html class="reftest-wait">
<title>transform-box: fill-box, image mutated</title>
<link rel="match" href="reference/greensquare200x200.html">
<link rel="help" href="https://drafts.csswg.org/css-transforms/#transform-box">
<style>
#target {
transform-box: fill-box;
transform: translate(-50%, 0);
}
</style>
<p>There should be a green 200x200 rectangle below, and no red.</p>
<svg width="400" height="200">
<rect width="200" height="200" fill="red"/>
<image id="target" x="100" width="100" height="200"
href="/css/css-transforms/support/1x1-green.png"/>
</svg>
<script>
requestAnimationFrame(function() {
requestAnimationFrame(function() {
document.querySelector('#target').setAttribute('width', 200);
document.documentElement.classList.remove('reftest-wait');
});
});
</script>
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