2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
3 * Copyright (C) 2006 Apple Inc. All rights reserved.
4 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 #include "core/layout/svg/LayoutSVGInline.h"
26 #include "core/layout/svg/LayoutSVGText.h"
27 #include "core/layout/svg/SVGLayoutSupport.h"
28 #include "core/layout/svg/SVGResourcesCache.h"
29 #include "core/layout/svg/line/SVGInlineFlowBox.h"
30 #include "core/svg/SVGAElement.h"
34 bool LayoutSVGInline::isChildAllowed(LayoutObject
* child
, const ComputedStyle
& style
) const
37 return SVGLayoutSupport::isLayoutableTextNode(child
);
39 if (isSVGAElement(*node())) {
40 // Disallow direct descendant 'a'.
41 if (isSVGAElement(*child
->node()))
45 if (!child
->isSVGInline() && !child
->isSVGInlineText())
48 return LayoutInline::isChildAllowed(child
, style
);
51 LayoutSVGInline::LayoutSVGInline(Element
* element
)
52 : LayoutInline(element
)
54 setAlwaysCreateLineBoxes();
57 InlineFlowBox
* LayoutSVGInline::createInlineFlowBox()
59 InlineFlowBox
* box
= new SVGInlineFlowBox(*this);
60 box
->setHasVirtualLogicalHeight();
64 FloatRect
LayoutSVGInline::objectBoundingBox() const
66 if (const LayoutSVGText
* textRoot
= LayoutSVGText::locateLayoutSVGTextAncestor(this))
67 return textRoot
->objectBoundingBox();
72 FloatRect
LayoutSVGInline::strokeBoundingBox() const
74 if (const LayoutSVGText
* textRoot
= LayoutSVGText::locateLayoutSVGTextAncestor(this))
75 return textRoot
->strokeBoundingBox();
80 FloatRect
LayoutSVGInline::paintInvalidationRectInLocalCoordinates() const
82 if (const LayoutSVGText
* textRoot
= LayoutSVGText::locateLayoutSVGTextAncestor(this))
83 return textRoot
->paintInvalidationRectInLocalCoordinates();
88 LayoutRect
LayoutSVGInline::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject
* paintInvalidationContainer
, const PaintInvalidationState
* paintInvalidationState
) const
90 return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, paintInvalidationContainer
, paintInvalidationState
);
93 void LayoutSVGInline::mapLocalToContainer(const LayoutBoxModelObject
* paintInvalidationContainer
, TransformState
& transformState
, MapCoordinatesFlags
, bool* wasFixed
, const PaintInvalidationState
* paintInvalidationState
) const
95 SVGLayoutSupport::mapLocalToContainer(this, paintInvalidationContainer
, transformState
, wasFixed
, paintInvalidationState
);
98 const LayoutObject
* LayoutSVGInline::pushMappingToContainer(const LayoutBoxModelObject
* ancestorToStopAt
, LayoutGeometryMap
& geometryMap
) const
100 return SVGLayoutSupport::pushMappingToContainer(this, ancestorToStopAt
, geometryMap
);
103 void LayoutSVGInline::absoluteQuads(Vector
<FloatQuad
>& quads
, bool* wasFixed
) const
105 const LayoutSVGText
* textRoot
= LayoutSVGText::locateLayoutSVGTextAncestor(this);
109 FloatRect textBoundingBox
= textRoot
->strokeBoundingBox();
110 for (InlineFlowBox
* box
= firstLineBox(); box
; box
= box
->nextLineBox())
111 quads
.append(localToAbsoluteQuad(FloatRect(textBoundingBox
.x() + box
->x().toFloat(), textBoundingBox
.y() + box
->y().toFloat(), box
->logicalWidth().toFloat(), box
->logicalHeight().toFloat()), false, wasFixed
));
114 void LayoutSVGInline::willBeDestroyed()
116 SVGResourcesCache::clientDestroyed(this);
117 LayoutInline::willBeDestroyed();
120 void LayoutSVGInline::styleDidChange(StyleDifference diff
, const ComputedStyle
* oldStyle
)
122 if (diff
.needsFullLayout())
123 setNeedsBoundariesUpdate();
125 LayoutInline::styleDidChange(diff
, oldStyle
);
126 SVGResourcesCache::clientStyleChanged(this, diff
, styleRef());
129 void LayoutSVGInline::addChild(LayoutObject
* child
, LayoutObject
* beforeChild
)
131 LayoutInline::addChild(child
, beforeChild
);
132 SVGResourcesCache::clientWasAddedToTree(child
, child
->styleRef());
134 if (LayoutSVGText
* textLayoutObject
= LayoutSVGText::locateLayoutSVGTextAncestor(this))
135 textLayoutObject
->subtreeChildWasAdded(child
);
138 void LayoutSVGInline::removeChild(LayoutObject
* child
)
140 SVGResourcesCache::clientWillBeRemovedFromTree(child
);
142 LayoutSVGText
* textLayoutObject
= LayoutSVGText::locateLayoutSVGTextAncestor(this);
143 if (!textLayoutObject
) {
144 LayoutInline::removeChild(child
);
147 Vector
<SVGTextLayoutAttributes
*, 2> affectedAttributes
;
148 textLayoutObject
->subtreeChildWillBeRemoved(child
, affectedAttributes
);
149 LayoutInline::removeChild(child
);
150 textLayoutObject
->subtreeChildWasRemoved(affectedAttributes
);
153 void LayoutSVGInline::invalidateTreeIfNeeded(PaintInvalidationState
& paintInvalidationState
)
155 ASSERT(!needsLayout());
157 if (!shouldCheckForPaintInvalidation(paintInvalidationState
))
160 PaintInvalidationReason reason
= invalidatePaintIfNeeded(paintInvalidationState
, paintInvalidationState
.paintInvalidationContainer());
161 clearPaintInvalidationState(paintInvalidationState
);
163 if (reason
== PaintInvalidationDelayedFull
)
164 paintInvalidationState
.pushDelayedPaintInvalidationTarget(*this);
166 PaintInvalidationState
childTreeWalkState(paintInvalidationState
, *this, paintInvalidationState
.paintInvalidationContainer());
167 if (reason
== PaintInvalidationSVGResourceChange
)
168 childTreeWalkState
.setForceSubtreeInvalidationWithinContainer();
169 invalidatePaintOfSubtreesIfNeeded(childTreeWalkState
);