diff options
author | Feng Qian <fqian@google.com> | 2009-06-17 12:12:20 -0700 |
---|---|---|
committer | Feng Qian <fqian@google.com> | 2009-06-17 12:12:20 -0700 |
commit | 5f1ab04193ad0130ca8204aadaceae083aca9881 (patch) | |
tree | 5a92cd389e2cfe7fb67197ce14b38469462379f8 /WebCore/rendering/RenderSVGText.cpp | |
parent | 194315e5a908cc8ed67d597010544803eef1ac59 (diff) | |
download | external_webkit-5f1ab04193ad0130ca8204aadaceae083aca9881.zip external_webkit-5f1ab04193ad0130ca8204aadaceae083aca9881.tar.gz external_webkit-5f1ab04193ad0130ca8204aadaceae083aca9881.tar.bz2 |
Get WebKit r44544.
Diffstat (limited to 'WebCore/rendering/RenderSVGText.cpp')
-rw-r--r-- | WebCore/rendering/RenderSVGText.cpp | 112 |
1 files changed, 54 insertions, 58 deletions
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp index 8fef1f3..9e9809d 100644 --- a/WebCore/rendering/RenderSVGText.cpp +++ b/WebCore/rendering/RenderSVGText.cpp @@ -33,8 +33,10 @@ #include "FloatQuad.h" #include "GraphicsContext.h" #include "PointerEventsHitRules.h" +#include "RenderLayer.h" #include "RenderSVGRoot.h" #include "SVGLengthList.h" +#include "SVGRenderSupport.h" #include "SVGResourceFilter.h" #include "SVGRootInlineBox.h" #include "SVGTextElement.h" @@ -49,92 +51,79 @@ RenderSVGText::RenderSVGText(SVGTextElement* node) { } -IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/) +IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) { - // FIXME: handle non-root repaintContainer - FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true)); - -#if ENABLE(SVG_FILTERS) - // Filters can expand the bounding box - SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter()); - if (filter) - repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect)); -#endif - - if (!repaintRect.isEmpty()) - repaintRect.inflate(1); // inflate 1 pixel for antialiasing + return SVGRenderBase::clippedOverflowRectForRepaint(this, repaintContainer); +} - return enclosingIntRect(repaintRect); +void RenderSVGText::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& repaintRect, bool fixed) +{ + SVGRenderBase::computeRectForRepaint(this, repaintContainer, repaintRect, fixed); } -bool RenderSVGText::calculateLocalTransform() +void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const { - TransformationMatrix oldTransform = m_localTransform; - m_localTransform = static_cast<SVGTextElement*>(node())->animatedLocalTransform(); - return (oldTransform != m_localTransform); + SVGRenderBase::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState); } void RenderSVGText::layout() { ASSERT(needsLayout()); - + // FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware setNeedsLayout(true); - // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root - LayoutRepainter repainter(*this, checkForRepaintDuringLayout(), &m_absoluteBounds); + LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); // Best guess for a relative starting point SVGTextElement* text = static_cast<SVGTextElement*>(node()); int xOffset = (int)(text->x()->getFirst().value(text)); int yOffset = (int)(text->y()->getFirst().value(text)); setLocation(xOffset, yOffset); - - calculateLocalTransform(); - RenderBlock::layout(); + m_localTransform = text->animatedLocalTransform(); - m_absoluteBounds = absoluteClippedOverflowRect(); + RenderBlock::layout(); repainter.repaintAfterLayout(); - setNeedsLayout(false); } RootInlineBox* RenderSVGText::createRootBox() { - return new (renderArena()) SVGRootInlineBox(this); + RootInlineBox* box = new (renderArena()) SVGRootInlineBox(this); + box->setIsSVG(true); + return box; } -bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction) +bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) { PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, 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))) { - TransformationMatrix totalTransform = absoluteTransform(); - double localX, localY; - totalTransform.inverse().map(_x, _y, localX, localY); - FloatPoint hitPoint(_x, _y); - return RenderBlock::nodeAtPoint(request, result, (int)localX, (int)localY, _tx, _ty, hitTestAction); + FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); + return RenderBlock::nodeAtPoint(request, result, (int)localPoint.x(), (int)localPoint.y(), 0, 0, hitTestAction); } } return false; } -void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool) +bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction) +{ + ASSERT_NOT_REACHED(); + return false; +} + +void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int) { RenderSVGRoot* root = findSVGRootObject(parent()); if (!root) return; - - FloatPoint absPos = localToAbsolute(); - - TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform(); - // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard + // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'. for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); @@ -142,24 +131,20 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool) InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) { FloatRect boxRect(box->x(), box->y(), box->width(), box->height()); - boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f())); - // FIXME: broken with CSS transforms - rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect))); + // FIXME: crawling up the parent chain to map each rect is very inefficient + // we should compute the absoluteTransform outside this loop first. + rects.append(enclosingIntRect(localToAbsoluteQuad(boxRect).boundingBox())); } } } -void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool) +void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads) { RenderSVGRoot* root = findSVGRootObject(parent()); if (!root) return; - - FloatPoint absPos = localToAbsolute(); - - TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform(); - // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard + // Don't use objectBoundingBox here, as it's unites the selection rects. Makes it hard // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'. for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); @@ -167,34 +152,44 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool) InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) { FloatRect boxRect(box->x(), box->y(), box->width(), box->height()); - boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f())); - // FIXME: broken with CSS transforms - quads.append(absoluteTransform().mapRect(boxRect)); + // FIXME: crawling up the parent chain to map each quad is very inefficient + // we should compute the absoluteTransform outside this loop first. + quads.append(localToAbsoluteQuad(boxRect)); } } } void RenderSVGText::paint(PaintInfo& paintInfo, int, int) { - RenderObject::PaintInfo pi(paintInfo); - pi.rect = absoluteTransform().inverse().mapRect(pi.rect); + PaintInfo pi(paintInfo); + pi.context->save(); + applyTransformToPaintInfo(pi, localToParentTransform()); RenderBlock::paint(pi, 0, 0); + pi.context->restore(); } -FloatRect RenderSVGText::relativeBBox(bool includeStroke) const +FloatRect RenderSVGText::objectBoundingBox() const { - FloatRect repaintRect; + FloatRect boundingBox; for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) { ASSERT(runBox->isInlineFlowBox()); InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox); for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) - repaintRect.unite(FloatRect(box->x(), box->y(), box->width(), box->height())); + boundingBox.unite(FloatRect(box->x(), box->y(), box->width(), box->height())); } + boundingBox.move(x(), y()); + return boundingBox; +} + +FloatRect RenderSVGText::repaintRectInLocalCoordinates() const +{ + FloatRect repaintRect = objectBoundingBox(); + // SVG needs to include the strokeWidth(), not the textStrokeWidth(). - if (includeStroke && style()->svgStyle()->hasStroke()) { + if (style()->svgStyle()->hasStroke()) { float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f); #if ENABLE(SVG_FONTS) @@ -210,7 +205,8 @@ FloatRect RenderSVGText::relativeBBox(bool includeStroke) const repaintRect.inflate(strokeWidth); } - repaintRect.move(x(), y()); + repaintRect.unite(filterBoundingBoxForRenderer(this)); + return repaintRect; } |