diff options
author | Steve Block <steveblock@google.com> | 2011-05-13 06:44:40 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-13 06:44:40 -0700 |
commit | 08014c20784f3db5df3a89b73cce46037b77eb59 (patch) | |
tree | 47749210d31e19e6e2f64036fa8fae2ad693476f /Source/WebCore/rendering/svg/RenderSVGText.cpp | |
parent | 860220379e56aeb66424861ad602b07ee22b4055 (diff) | |
parent | 4c3661f7918f8b3f139f824efb7855bedccb4c94 (diff) | |
download | external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.zip external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.tar.gz external_webkit-08014c20784f3db5df3a89b73cce46037b77eb59.tar.bz2 |
Merge changes Ide388898,Ic49f367c,I1158a808,Iacb6ca5d,I2100dd3a,I5c1abe54,Ib0ef9902,I31dbc523,I570314b3
* changes:
Merge WebKit at r75315: Update WebKit version
Merge WebKit at r75315: Add FrameLoaderClient PageCache stubs
Merge WebKit at r75315: Stub out AXObjectCache::remove()
Merge WebKit at r75315: Fix ImageBuffer
Merge WebKit at r75315: Fix PluginData::initPlugins()
Merge WebKit at r75315: Fix conflicts
Merge WebKit at r75315: Fix Makefiles
Merge WebKit at r75315: Move Android-specific WebCore files to Source
Merge WebKit at r75315: Initial merge by git.
Diffstat (limited to 'Source/WebCore/rendering/svg/RenderSVGText.cpp')
-rw-r--r-- | Source/WebCore/rendering/svg/RenderSVGText.cpp | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp new file mode 100644 index 0000000..01a92b0 --- /dev/null +++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> + * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> + * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2008 Rob Buis <buis@kde.org> + * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> + * 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 "config.h" + +#if ENABLE(SVG) +#include "RenderSVGText.h" + +#include "FloatConversion.h" +#include "FloatQuad.h" +#include "GraphicsContext.h" +#include "HitTestRequest.h" +#include "PointerEventsHitRules.h" +#include "RenderLayer.h" +#include "RenderSVGResource.h" +#include "RenderSVGRoot.h" +#include "SVGLengthList.h" +#include "SVGRenderSupport.h" +#include "SVGRootInlineBox.h" +#include "SVGTextElement.h" +#include "SVGTextLayoutAttributesBuilder.h" +#include "SVGTransformList.h" +#include "SVGURIReference.h" +#include "SimpleFontData.h" +#include "TransformState.h" +#include "VisiblePosition.h" + +namespace WebCore { + +RenderSVGText::RenderSVGText(SVGTextElement* node) + : RenderSVGBlock(node) + , m_needsPositioningValuesUpdate(true) + , m_needsTransformUpdate(true) +{ +} + +RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject* start) +{ + ASSERT(start); + while (start && !start->isSVGText()) + start = start->parent(); + if (!start || !start->isSVGText()) + return 0; + return toRenderSVGText(start); +} + +const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObject* start) +{ + ASSERT(start); + while (start && !start->isSVGText()) + start = start->parent(); + if (!start || !start->isSVGText()) + return 0; + return toRenderSVGText(start); +} + +IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) +{ + return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer); +} + +void RenderSVGText::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed) +{ + SVGRenderSupport::computeRectForRepaint(this, repaintContainer, repaintRect, fixed); +} + +void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const +{ + SVGRenderSupport::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState); +} + +void RenderSVGText::layout() +{ + ASSERT(needsLayout()); + LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); + + bool updateCachedBoundariesInParents = false; + if (m_needsTransformUpdate) { + SVGTextElement* text = static_cast<SVGTextElement*>(node()); + m_localTransform = text->animatedLocalTransform(); + m_needsTransformUpdate = false; + updateCachedBoundariesInParents = true; + } + + if (m_needsPositioningValuesUpdate) { + // Perform SVG text layout phase one (see SVGTextLayoutAttributesBuilder for details). + SVGTextLayoutAttributesBuilder layoutAttributesBuilder; + layoutAttributesBuilder.buildLayoutAttributesForTextSubtree(this); + m_needsPositioningValuesUpdate = false; + updateCachedBoundariesInParents = true; + } + + // Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text. + // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions. + ASSERT(!isInline()); + ASSERT(!layoutOnlyPositionedObjects()); + ASSERT(!scrollsOverflow()); + ASSERT(!hasControlClip()); + ASSERT(!hasColumns()); + ASSERT(!positionedObjects()); + ASSERT(!m_overflow); + ASSERT(!isAnonymousBlock()); + + if (!firstChild()) + setChildrenInline(true); + + // FIXME: We need to find a way to only layout the child boxes, if needed. + FloatRect oldBoundaries = objectBoundingBox(); + ASSERT(childrenInline()); + forceLayoutInlineChildren(); + + if (!updateCachedBoundariesInParents) + updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); + + // Invalidate all resources of this client if our layout changed. + if (m_everHadLayout && selfNeedsLayout()) + SVGResourcesCache::clientLayoutChanged(this); + + // If our bounds changed, notify the parents. + if (updateCachedBoundariesInParents) + RenderSVGBlock::setNeedsBoundariesUpdate(); + + repainter.repaintAfterLayout(); + setNeedsLayout(false); +} + +RootInlineBox* RenderSVGText::createRootInlineBox() +{ + RootInlineBox* box = new (renderArena()) SVGRootInlineBox(this); + box->setHasVirtualLogicalHeight(); + return box; +} + +bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) +{ + PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style()->pointerEvents()); + bool isVisible = (style()->visibility() == VISIBLE); + if (isVisible || !hitRules.requireVisible) { + if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke)) + || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) { + FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); + + if (!SVGRenderSupport::pointInClippingArea(this, localPoint)) + return false; + + return RenderBlock::nodeAtPoint(request, result, (int)localPoint.x(), (int)localPoint.y(), 0, 0, hitTestAction); + } + } + + return false; +} + +bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction) +{ + ASSERT_NOT_REACHED(); + return false; +} + +VisiblePosition RenderSVGText::positionForPoint(const IntPoint& pointInContents) +{ + RootInlineBox* rootBox = firstRootBox(); + if (!rootBox) + return createVisiblePosition(0, DOWNSTREAM); + + ASSERT(rootBox->isSVGRootInlineBox()); + ASSERT(!rootBox->nextRootBox()); + ASSERT(childrenInline()); + + InlineBox* closestBox = static_cast<SVGRootInlineBox*>(rootBox)->closestLeafChildForPosition(pointInContents); + if (!closestBox) + return createVisiblePosition(0, DOWNSTREAM); + + return closestBox->renderer()->positionForPoint(IntPoint(pointInContents.x(), closestBox->m_y)); +} + +void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads) +{ + quads.append(localToAbsoluteQuad(strokeBoundingBox())); +} + +void RenderSVGText::paint(PaintInfo& paintInfo, int, int) +{ + if (paintInfo.context->paintingDisabled()) + return; + + if (paintInfo.phase != PaintPhaseForeground + && paintInfo.phase != PaintPhaseSelfOutline + && paintInfo.phase != PaintPhaseSelection) + return; + + PaintInfo blockInfo(paintInfo); + blockInfo.context->save(); + blockInfo.applyTransform(localToParentTransform()); + RenderBlock::paint(blockInfo, 0, 0); + blockInfo.context->restore(); +} + +FloatRect RenderSVGText::strokeBoundingBox() const +{ + FloatRect strokeBoundaries = objectBoundingBox(); + const SVGRenderStyle* svgStyle = style()->svgStyle(); + if (!svgStyle->hasStroke()) + return strokeBoundaries; + + ASSERT(node()); + ASSERT(node()->isSVGElement()); + strokeBoundaries.inflate(svgStyle->strokeWidth().value(static_cast<SVGElement*>(node()))); + return strokeBoundaries; +} + +FloatRect RenderSVGText::repaintRectInLocalCoordinates() const +{ + FloatRect repaintRect = strokeBoundingBox(); + SVGRenderSupport::intersectRepaintRectWithResources(this, repaintRect); + + if (const ShadowData* textShadow = style()->textShadow()) + textShadow->adjustRectForShadow(repaintRect); + + return repaintRect; +} + +// Fix for <rdar://problem/8048875>. We should not render :first-line CSS Style +// in a SVG text element context. +RenderBlock* RenderSVGText::firstLineBlock() const +{ + return 0; +} + +// Fix for <rdar://problem/8048875>. We should not render :first-letter CSS Style +// in a SVG text element context. +void RenderSVGText::updateFirstLetter() +{ +} + +} + +#endif // ENABLE(SVG) |