diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-20 13:01:08 +0200 |
| commit | 49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch) | |
| tree | 5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/WebCore/rendering/svg | |
| parent | b211c645d8ab690f713515dfdc84d80b11c27d2c (diff) | |
| download | qtwebkit-49233e234e5c787396cadb2cea33b31ae0cd65c1.tar.gz | |
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/WebCore/rendering/svg')
14 files changed, 67 insertions, 25 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp index 7b2866113..380275396 100644 --- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp @@ -163,11 +163,6 @@ void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutP void RenderSVGContainer::updateCachedBoundaries() { - m_objectBoundingBox = FloatRect(); - m_objectBoundingBoxValid = false; - m_strokeBoundingBox = FloatRect(); - m_repaintBoundingBox = FloatRect(); - SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox); SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox); } diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp index eff707724..454f7aa6d 100644 --- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp @@ -232,9 +232,7 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c ASSERT(styleResolver); // Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified - AffineTransform ctm; - SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm); - scalingFactor = narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); + scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer); if (scalingFactor == 1 || !scalingFactor || style->fontDescription().textRenderingMode() == GeometricPrecision) { scalingFactor = 1; scaledFont = style->font(); diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp index c1c27b09a..cf3079c06 100644 --- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp @@ -171,8 +171,10 @@ bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const Float if (!isGraphicsElement(renderer)) return false; AffineTransform ctm; - getElementCTM(static_cast<SVGElement*>(renderer->node()), ctm); - return intersectsAllowingEmpty(rect, ctm.mapRect(renderer->repaintRectInLocalCoordinates())); + SVGElement* svgElement = static_cast<SVGElement*>(renderer->node()); + getElementCTM(svgElement, ctm); + ASSERT(svgElement->renderer()); + return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates())); } bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRect& rect) @@ -182,8 +184,10 @@ bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRec if (!isGraphicsElement(renderer)) return false; AffineTransform ctm; - getElementCTM(static_cast<SVGElement*>(renderer->node()), ctm); - return rect.contains(ctm.mapRect(renderer->repaintRectInLocalCoordinates())); + SVGElement* svgElement = static_cast<SVGElement*>(renderer->node()); + getElementCTM(svgElement, ctm); + ASSERT(svgElement->renderer()); + return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates())); } } // namespace WebCore diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp index 80760fd48..3e223ed3b 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp @@ -24,6 +24,7 @@ #include "RenderSVGRoot.h" #include "RenderView.h" +#include "SVGRenderingContext.h" #include "SVGResourcesCache.h" #include "SVGStyledTransformableElement.h" @@ -170,6 +171,27 @@ void RenderSVGResourceContainer::registerResource() } } +bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform) +{ + ASSERT_UNUSED(object, object); +#if USE(CG) + UNUSED_PARAM(resourceTransform); + return false; +#else + // This method should only be called for RenderObjects that deal with text rendering. Cmp. RenderObject.h's is*() methods. + ASSERT(object->isSVGText() || object->isSVGTextPath() || object->isSVGInline()); + + // In text drawing, the scaling part of the graphics context CTM is removed, compare SVGInlineTextBox::paintTextWithShadows. + // So, we use that scaling factor here, too, and then push it down to pattern or gradient space + // in order to keep the pattern or gradient correctly scaled. + float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(object); + if (scalingFactor == 1) + return false; + resourceTransform.scale(scalingFactor); + return true; +#endif +} + // FIXME: This does not belong here. AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform) { diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h index b7473d927..1e8e62de8 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h +++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h @@ -38,6 +38,7 @@ public: virtual bool isSVGResourceContainer() const { return true; } virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; } + static bool shouldTransformOnTextPainting(RenderObject*, AffineTransform&); static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform); void idChanged(); diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp index f8f493db8..58e0079b2 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp @@ -166,6 +166,13 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* calculateGradientTransform(gradientTransform); gradientData->userspaceTransform *= gradientTransform; + if (isPaintingText) { + // Depending on font scaling factor, we may need to rescale the gradient here since + // text painting removes the scale factor from the context. + AffineTransform additionalTextTransform; + if (shouldTransformOnTextPainting(object, additionalTextTransform)) + gradientData->userspaceTransform *= additionalTextTransform; + } gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform); } diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp index 15d647689..b4af99918 100644 --- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp @@ -133,6 +133,12 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* if (!patternTransform.isIdentity()) patternData->transform = patternTransform * patternData->transform; + // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows. + if (resourceMode & ApplyToTextMode) { + AffineTransform additionalTextTransformation; + if (shouldTransformOnTextPainting(object, additionalTextTransformation)) + patternData->transform *= additionalTextTransformation; + } patternData->pattern->setPatternSpaceTransform(patternData->transform); } diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp index 663245333..58a715309 100644 --- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp @@ -404,11 +404,6 @@ const RenderObject* RenderSVGRoot::pushMappingToContainer(const RenderBoxModelOb void RenderSVGRoot::updateCachedBoundaries() { - m_objectBoundingBox = FloatRect(); - m_objectBoundingBoxValid = false; - m_strokeBoundingBox = FloatRect(); - m_repaintBoundingBox = FloatRect(); - SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox); SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox); m_repaintBoundingBox.inflate(borderAndPaddingWidth()); diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp index c30fad59b..3ed63ddd6 100644 --- a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp @@ -36,7 +36,6 @@ namespace WebCore { RenderSVGTextPath::RenderSVGTextPath(Node* n) : RenderSVGInline(n) - , m_startOffset(0) , m_exactAlignment(true) , m_stretchMethod(false) { diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.h b/Source/WebCore/rendering/svg/RenderSVGTextPath.h index f1871b0f6..be156ba48 100644 --- a/Source/WebCore/rendering/svg/RenderSVGTextPath.h +++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.h @@ -40,8 +40,6 @@ public: private: virtual const char* renderName() const { return "RenderSVGTextPath"; } - float m_startOffset; - bool m_exactAlignment : 1; bool m_stretchMethod : 1; diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp index 24e9a82f7..9302aef80 100644 --- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp +++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp @@ -44,7 +44,7 @@ using namespace std; namespace WebCore { -class ExpectedSVGInlineTextBoxSize : public InlineTextBox { +struct ExpectedSVGInlineTextBoxSize : public InlineTextBox { float float1; uint32_t bitfields : 5; void* pointer; diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp index 177ce9c44..0bfb0a527 100644 --- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp +++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp @@ -121,6 +121,13 @@ static inline void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& o void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox) { + objectBoundingBox = FloatRect(); + objectBoundingBoxValid = false; + strokeBoundingBox = FloatRect(); + + // When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes + // the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound + // the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also. for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) { if (current->isSVGHiddenContainer()) continue; @@ -128,14 +135,14 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* contain const AffineTransform& transform = current->localToParentTransform(); if (transform.isIdentity()) { updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox()); - strokeBoundingBox.unite(current->strokeBoundingBox()); - repaintBoundingBox.unite(current->repaintRectInLocalCoordinates()); + strokeBoundingBox.unite(current->repaintRectInLocalCoordinates()); } else { updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox())); - strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox())); - repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates())); + strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates())); } } + + repaintBoundingBox = strokeBoundingBox; } bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo) diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp index 80f53ef17..e2adb3063 100644 --- a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp +++ b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp @@ -167,6 +167,15 @@ static AffineTransform& currentContentTransformation() return s_currentContentTransformation; } +float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject* renderer) +{ + ASSERT(renderer); + + AffineTransform ctm; + calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm); + return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); +} + void SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform) { const RenderObject* current = renderer; diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.h b/Source/WebCore/rendering/svg/SVGRenderingContext.h index 4649d9ab7..5d38ce495 100644 --- a/Source/WebCore/rendering/svg/SVGRenderingContext.h +++ b/Source/WebCore/rendering/svg/SVGRenderingContext.h @@ -83,6 +83,7 @@ public: static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&); static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, OwnPtr<ImageBuffer>&, bool safeToClear); + static float calculateScreenFontSizeScalingFactor(const RenderObject*); static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform); static IntSize clampedAbsoluteSize(const IntSize&); static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect); |
