| /* |
| * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> |
| * Copyright (C) 2006 Apple Inc. All rights reserved. |
| * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| * |
| * 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. |
| */ |
| |
| #include "core/layout/svg/LayoutSVGInline.h" |
| |
| #include "core/layout/LayoutView.h" |
| #include "core/layout/svg/LayoutSVGText.h" |
| #include "core/layout/svg/SVGLayoutSupport.h" |
| #include "core/layout/svg/SVGResourcesCache.h" |
| #include "core/layout/svg/line/SVGInlineFlowBox.h" |
| #include "core/svg/SVGAElement.h" |
| |
| namespace blink { |
| |
| bool LayoutSVGInline::isChildAllowed(LayoutObject* child, |
| const ComputedStyle& style) const { |
| if (child->isText()) |
| return SVGLayoutSupport::isLayoutableTextNode(child); |
| |
| if (isSVGAElement(*node())) { |
| // Disallow direct descendant 'a'. |
| if (isSVGAElement(*child->node())) |
| return false; |
| } |
| |
| if (!child->isSVGInline() && !child->isSVGInlineText()) |
| return false; |
| |
| return LayoutInline::isChildAllowed(child, style); |
| } |
| |
| LayoutSVGInline::LayoutSVGInline(Element* element) : LayoutInline(element) { |
| setAlwaysCreateLineBoxes(); |
| } |
| |
| InlineFlowBox* LayoutSVGInline::createInlineFlowBox() { |
| InlineFlowBox* box = new SVGInlineFlowBox(LineLayoutItem(this)); |
| box->setHasVirtualLogicalHeight(); |
| return box; |
| } |
| |
| FloatRect LayoutSVGInline::objectBoundingBox() const { |
| if (const LayoutSVGText* textRoot = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this)) |
| return textRoot->objectBoundingBox(); |
| |
| return FloatRect(); |
| } |
| |
| FloatRect LayoutSVGInline::strokeBoundingBox() const { |
| if (const LayoutSVGText* textRoot = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this)) |
| return textRoot->strokeBoundingBox(); |
| |
| return FloatRect(); |
| } |
| |
| FloatRect LayoutSVGInline::paintInvalidationRectInLocalSVGCoordinates() const { |
| if (const LayoutSVGText* textRoot = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this)) |
| return textRoot->paintInvalidationRectInLocalSVGCoordinates(); |
| |
| return FloatRect(); |
| } |
| |
| LayoutRect LayoutSVGInline::absoluteClippedOverflowRect() const { |
| return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, |
| *view()); |
| } |
| |
| void LayoutSVGInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, |
| TransformState& transformState, |
| MapCoordinatesFlags flags) const { |
| SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, flags); |
| } |
| |
| const LayoutObject* LayoutSVGInline::pushMappingToContainer( |
| const LayoutBoxModelObject* ancestorToStopAt, |
| LayoutGeometryMap& geometryMap) const { |
| return SVGLayoutSupport::pushMappingToContainer(this, ancestorToStopAt, |
| geometryMap); |
| } |
| |
| void LayoutSVGInline::absoluteQuads(Vector<FloatQuad>& quads) const { |
| const LayoutSVGText* textRoot = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this); |
| if (!textRoot) |
| return; |
| |
| FloatRect textBoundingBox = textRoot->strokeBoundingBox(); |
| for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) |
| quads.append( |
| localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x().toFloat(), |
| textBoundingBox.y() + box->y().toFloat(), |
| box->logicalWidth().toFloat(), |
| box->logicalHeight().toFloat()), |
| false)); |
| } |
| |
| void LayoutSVGInline::willBeDestroyed() { |
| SVGResourcesCache::clientDestroyed(this); |
| LayoutInline::willBeDestroyed(); |
| } |
| |
| void LayoutSVGInline::styleDidChange(StyleDifference diff, |
| const ComputedStyle* oldStyle) { |
| if (diff.needsFullLayout()) |
| setNeedsBoundariesUpdate(); |
| |
| LayoutInline::styleDidChange(diff, oldStyle); |
| SVGResourcesCache::clientStyleChanged(this, diff, styleRef()); |
| } |
| |
| void LayoutSVGInline::addChild(LayoutObject* child, LayoutObject* beforeChild) { |
| LayoutInline::addChild(child, beforeChild); |
| SVGResourcesCache::clientWasAddedToTree(child, child->styleRef()); |
| |
| if (LayoutSVGText* textLayoutObject = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this)) |
| textLayoutObject->subtreeChildWasAdded(); |
| } |
| |
| void LayoutSVGInline::removeChild(LayoutObject* child) { |
| SVGResourcesCache::clientWillBeRemovedFromTree(child); |
| |
| if (LayoutSVGText* textLayoutObject = |
| LayoutSVGText::locateLayoutSVGTextAncestor(this)) |
| textLayoutObject->subtreeChildWillBeRemoved(); |
| LayoutInline::removeChild(child); |
| } |
| |
| void LayoutSVGInline::invalidateTreeIfNeeded( |
| const PaintInvalidationState& paintInvalidationState) { |
| // TODO(wangxianzhu): Verify if the inherited |
| // LayoutBoxModelObject::invalidateTreeIfNeeded() is applicable here. |
| // If yes, remove this overriding method. |
| LayoutObject::invalidateTreeIfNeeded(paintInvalidationState); |
| } |
| |
| } // namespace blink |