summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h
blob: 2cddf75b0040da038d9ee3ae24dcaaa59755f1c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright (C) 2006 Apple Computer, Inc.
 * Copyright (C) 2009 Google, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FOREIGN_OBJECT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FOREIGN_OBJECT_H_

#include "third_party/blink/renderer/core/layout/svg/layout_svg_block.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"

namespace blink {

class SVGForeignObjectElement;

// LayoutSVGForeignObject is the LayoutObject associated with <foreignobject>.
// http://www.w3.org/TR/SVG/extend.html#ForeignObjectElement
//
// Foreign object is a way of inserting arbitrary non-SVG content into SVG.
// A good example of this is HTML in SVG. Because of this, CSS content has to
// be aware of SVG: e.g. when determining containing blocks we stop at the
// enclosing foreign object (see LayoutObject::canContainFixedPositionObjects).
//
// Note that SVG is also allowed in HTML with the HTML5 parsing rules so SVG
// content also has to be aware of CSS objects.
// See http://www.w3.org/TR/html5/syntax.html#elements-0 with the rules for
// 'foreign elements'. TODO(jchaffraix): Find a better place for this paragraph.
//
// The coordinate space for the descendants of the foreignObject does not
// include the effective zoom (it is baked into any lengths as usual). The
// transform that defines the userspace of the element is:
//
//   [CSS transform] * [inverse effective zoom] (* ['x' and 'y' translation])
//
// Because of this, the frame rect and visual rect includes effective zoom. The
// object bounding box (ObjectBoundingBox method) is however not zoomed to be
// compatible with the expectations of the getBBox() DOM interface.
class LayoutSVGForeignObject final : public LayoutSVGBlock {
 public:
  explicit LayoutSVGForeignObject(SVGForeignObjectElement*);
  ~LayoutSVGForeignObject() override;

  const char* GetName() const override {
    NOT_DESTROYED();
    return "LayoutSVGForeignObject";
  }

  bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;

  void Paint(const PaintInfo&) const override;

  void UpdateLayout() override;

  FloatRect ObjectBoundingBox() const override {
    NOT_DESTROYED();
    return viewport_;
  }
  FloatRect StrokeBoundingBox() const override {
    NOT_DESTROYED();
    return ObjectBoundingBox();
  }
  FloatRect VisualRectInLocalSVGCoordinates() const override {
    NOT_DESTROYED();
    return FloatRect(FrameRect());
  }
  bool IsObjectBoundingBoxValid() const {
    NOT_DESTROYED();
    return !viewport_.IsEmpty();
  }

  bool NodeAtPoint(HitTestResult&,
                   const HitTestLocation&,
                   const PhysicalOffset&,
                   HitTestAction) override;

  // A method to call when recursively hit testing from an SVG parent.
  // Since LayoutSVGRoot has a PaintLayer always, this will cause a
  // trampoline through PaintLayer::HitTest and back to a call to NodeAtPoint
  // on this object. This is why there are two methods.
  bool NodeAtPointFromSVG(HitTestResult&,
                          const HitTestLocation&,
                          const PhysicalOffset&,
                          HitTestAction);

  bool IsOfType(LayoutObjectType type) const override {
    NOT_DESTROYED();
    return type == kLayoutObjectSVGForeignObject ||
           LayoutSVGBlock::IsOfType(type);
  }

  PaintLayerType LayerTypeRequired() const override;

  bool CreatesNewFormattingContext() const final {
    NOT_DESTROYED();
    // This is the root of a foreign object. Don't let anything inside it escape
    // to our ancestors.
    return true;
  }

 private:
  void UpdateLogicalWidth() override;
  void ComputeLogicalHeight(LayoutUnit logical_height,
                            LayoutUnit logical_top,
                            LogicalExtentComputedValues&) const override;
  void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
  AffineTransform LocalToSVGParentTransform() const override;

  // The resolved viewport in the regular SVG coordinate space (after any
  // 'transform' has been applied but without zoom-adjustment).
  FloatRect viewport_;
};

template <>
struct DowncastTraits<LayoutSVGForeignObject> {
  static bool AllowFrom(const LayoutObject& object) {
    return object.IsSVGForeignObject();
  }
};

}  // namespace blink

#endif