summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGSVGElement.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-06-01 10:36:58 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-06-01 10:36:58 +0200
commitb1e9e47fa11f608ae16bc07f97a2acf95bf80272 (patch)
treec88c45e80c9c44506e7cdf9a3bb39ebf82a8cd5b /Source/WebCore/svg/SVGSVGElement.cpp
parentbe01689f43cf6882cf670d33df49ead1f570c53a (diff)
downloadqtwebkit-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.cpp109
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;