diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-06-01 10:36:58 +0200 |
commit | b1e9e47fa11f608ae16bc07f97a2acf95bf80272 (patch) | |
tree | c88c45e80c9c44506e7cdf9a3bb39ebf82a8cd5b /Source/WebCore/svg/SVGSVGElement.cpp | |
parent | be01689f43cf6882cf670d33df49ead1f570c53a (diff) | |
download | qtwebkit-b1e9e47fa11f608ae16bc07f97a2acf95bf80272.tar.gz |
Imported WebKit commit 499c84c99aa98e9870fa7eaa57db476c6d160d46 (http://svn.webkit.org/repository/webkit/trunk@119200)
Weekly update :). Particularly relevant changes for Qt are the use of the WebCore image decoders and direct usage
of libpng/libjpeg if available in the system.
Diffstat (limited to 'Source/WebCore/svg/SVGSVGElement.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGSVGElement.cpp | 109 |
1 files changed, 66 insertions, 43 deletions
diff --git a/Source/WebCore/svg/SVGSVGElement.cpp b/Source/WebCore/svg/SVGSVGElement.cpp index 0fbda9d4a..8cde7d516 100644 --- a/Source/WebCore/svg/SVGSVGElement.cpp +++ b/Source/WebCore/svg/SVGSVGElement.cpp @@ -46,13 +46,13 @@ #include "SMILTimeContainer.h" #include "SVGAngle.h" #include "SVGElementInstance.h" +#include "SVGFitToViewBox.h" #include "SVGNames.h" #include "SVGPreserveAspectRatio.h" #include "SVGTransform.h" #include "SVGTransformList.h" #include "SVGViewElement.h" #include "SVGViewSpec.h" -#include "SVGZoomAndPan.h" #include "SVGZoomEvent.h" #include "ScriptEventListener.h" #include "StaticNodeList.h" @@ -103,6 +103,8 @@ PassRefPtr<SVGSVGElement> SVGSVGElement::create(const QualifiedName& tagName, Do SVGSVGElement::~SVGSVGElement() { + if (m_viewSpec) + m_viewSpec->resetContextElement(); document()->unregisterForPageCacheSuspensionCallbacks(this); // There are cases where removedFromDocument() is not called. // see ContainerNode::removeAllChildren, called by its destructor. @@ -170,10 +172,10 @@ float SVGSVGElement::screenPixelToMillimeterY() const return pixelUnitToMillimeterY(); } -SVGViewSpec* SVGSVGElement::currentView() const +SVGViewSpec* SVGSVGElement::currentView() { if (!m_viewSpec) - m_viewSpec = adoptPtr(new SVGViewSpec(const_cast<SVGSVGElement*>(this))); + m_viewSpec = SVGViewSpec::create(this); return m_viewSpec.get(); } @@ -269,7 +271,7 @@ void SVGSVGElement::parseAttribute(const Attribute& attribute) else if (SVGTests::parseAttribute(attribute) || SVGLangSpace::parseAttribute(attribute) || SVGExternalResourcesRequired::parseAttribute(attribute) - || SVGFitToViewBox::parseAttribute(document(), attribute) + || SVGFitToViewBox::parseAttribute(this, attribute) || SVGZoomAndPan::parseAttribute(this, attribute)) { } else SVGStyledLocatableElement::parseAttribute(attribute); @@ -525,11 +527,8 @@ bool SVGSVGElement::selfHasRelativeLengths() const FloatRect SVGSVGElement::currentViewBoxRect() const { - if (useCurrentView()) { - if (SVGViewSpec* view = currentView()) // what if we should use it but it is not set? - return view->viewBox(); - return FloatRect(); - } + if (m_useCurrentView) + return m_viewSpec ? m_viewSpec->viewBox() : FloatRect(); FloatRect useViewBox = viewBox(); if (!useViewBox.isEmpty()) @@ -646,71 +645,95 @@ Length SVGSVGElement::intrinsicHeight(ConsiderCSSMode mode) const AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const { - AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio(), viewWidth, viewHeight); - if (useCurrentView() && currentView()) { - AffineTransform transform; - if (currentView()->transformBaseValue().concatenate(transform)) - ctm *= transform; - } + if (!m_useCurrentView || !m_viewSpec) + return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio(), viewWidth, viewHeight); + + AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio(), viewWidth, viewHeight); + const SVGTransformList& transformList = m_viewSpec->transformBaseValue(); + if (transformList.isEmpty()) + return ctm; + + AffineTransform transform; + if (transformList.concatenate(transform)) + ctm *= transform; return ctm; } void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) { + RenderObject* renderer = this->renderer(); + SVGViewSpec* view = m_viewSpec.get(); + if (view) + view->reset(); + bool hadUseCurrentView = m_useCurrentView; + m_useCurrentView = false; + if (fragmentIdentifier.startsWith("xpointer(")) { // FIXME: XPointer references are ignored (https://bugs.webkit.org/show_bug.cgi?id=17491) - setUseCurrentView(false); - } else if (fragmentIdentifier.startsWith("svgView(")) { - if (currentView()->parseViewSpec(fragmentIdentifier)) - setUseCurrentView(true); - } else if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) { + if (renderer && hadUseCurrentView) + RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); + return; + } + + if (fragmentIdentifier.startsWith("svgView(")) { + if (!view) + view = currentView(); // Create the SVGViewSpec. + + if (view->parseViewSpec(fragmentIdentifier)) + m_useCurrentView = true; + else + view->reset(); + + if (renderer && (hadUseCurrentView || m_useCurrentView)) + RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); + return; + } + + // Spec: If the SVG fragment identifier addresses a ‘view’ element within an SVG document (e.g., MyDrawing.svg#MyView + // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport. + // Any view specification attributes included on the given ‘view’ element override the corresponding view specification + // attributes on the closest ancestor ‘svg’ element. + if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) { if (SVGViewElement* viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0) { SVGElement* element = SVGLocatable::nearestViewportElement(viewElement); if (element->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(element); svg->inheritViewAttributes(viewElement); - setUseCurrentView(true); + + if (RenderObject* renderer = svg->renderer()) + RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } } + return; } - if (!hadUseCurrentView) { - if (!m_useCurrentView) - return; - } else if (!m_useCurrentView) - currentView()->setTransformString(emptyString()); - - // Force a layout, otherwise RenderSVGRoots localToBorderBoxTransform won't be rebuild. - if (RenderObject* object = renderer()) - RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); - // FIXME: We need to decide which <svg> to focus on, and zoom to it. // FIXME: We need to actually "highlight" the viewTarget(s). } void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) { + SVGViewSpec* view = currentView(); + m_useCurrentView = true; + if (viewElement->hasAttribute(SVGNames::viewBoxAttr)) - currentView()->setViewBoxBaseValue(viewElement->viewBox()); + view->setViewBoxBaseValue(viewElement->viewBox()); else - currentView()->setViewBoxBaseValue(viewBox()); + view->setViewBoxBaseValue(viewBox()); - SVGPreserveAspectRatio aspectRatio; if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) - aspectRatio = viewElement->preserveAspectRatioBaseValue(); + view->setPreserveAspectRatioBaseValue(viewElement->preserveAspectRatioBaseValue()); else - aspectRatio = preserveAspectRatioBaseValue(); - currentView()->setPreserveAspectRatioBaseValue(aspectRatio); + view->setPreserveAspectRatioBaseValue(preserveAspectRatioBaseValue()); if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr)) - currentView()->setZoomAndPanBaseValue(viewElement->zoomAndPan()); - - if (RenderObject* object = renderer()) - RenderSVGResource::markForLayoutAndParentResourceInvalidation(object); + view->setZoomAndPanBaseValue(viewElement->zoomAndPan()); + else + view->setZoomAndPanBaseValue(zoomAndPan()); } - + void SVGSVGElement::documentWillSuspendForPageCache() { pauseAnimations(); @@ -731,7 +754,7 @@ Element* SVGSVGElement::getElementById(const AtomicString& id) const // Fall back to traversing our subtree. Duplicate ids are allowed, the first found will // be returned. - for (Node* node = traverseNextNode(this); node; node = node->traverseNextNode(this)) { + for (Node* node = firstChild(); node; node = node->traverseNextNode(this)) { if (!node->isElementNode()) continue; |