15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/RenderSVGResourceContainer.h"
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h"
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGRenderingContext.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGResourcesCache.h"
28591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/svg/SVGGraphicsElement.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/TemporaryChange.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static inline SVGDocumentExtensions& svgExtensionsFromElement(SVGElement* element)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(element);
378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return element->document().accessSVGExtensions();
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
40f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement* node)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : RenderSVGHiddenContainer(node)
42f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_isInLayout(false)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_id(node->getIdAttribute())
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    , m_invalidationMask(0)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_registered(false)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_isInvalidating(false)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderSVGResourceContainer::~RenderSVGResourceContainer()
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::layout()
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
56f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // FIXME: Investigate a way to detect and break resource layout dependency cycles early.
57f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    // Then we can remove this method altogether, and fall back onto RenderSVGHiddenContainer::layout().
581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(needsLayout());
591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_isInLayout)
601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    TemporaryChange<bool> inLayoutChange(m_isInLayout, true);
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderSVGHiddenContainer::layout();
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    clearInvalidationMask();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::willBeDestroyed()
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SVGResourcesCache::resourceDestroyed(this);
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderSVGHiddenContainer::willBeDestroyed();
73e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (m_registered)
74e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        svgExtensionsFromElement(element()).removeResource(m_id);
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_registered) {
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_registered = true;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        registerResource();
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::idChanged()
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Invalidate all our current clients.
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    removeAllClientsFromCache();
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Remove old id, that is guaranteed to be present in cache.
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    extensions.removeResource(m_id);
958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_id = element()->getIdAttribute();
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    registerResource();
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((m_clients.isEmpty() && m_clientLayers.isEmpty()) || m_isInvalidating)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (m_invalidationMask & mode)
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
10751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
10851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_invalidationMask |= mode;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_isInvalidating = true;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool needsLayout = mode == LayoutAndBoundariesInvalidation;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool markForInvalidation = mode != ParentOnlyInvalidation;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<RenderObject*>::iterator end = m_clients.end();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (HashSet<RenderObject*>::iterator it = m_clients.begin(); it != end; ++it) {
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* client = *it;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (client->isSVGResourceContainer()) {
117bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            toRenderSVGResourceContainer(client)->removeAllClientsFromCache(markForInvalidation);
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (markForInvalidation)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            markClientForInvalidation(client, mode);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderSVGResource::markForLayoutAndParentResourceInvalidation(client, needsLayout);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    markAllClientLayersForInvalidation();
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_isInvalidating = false;
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void RenderSVGResourceContainer::markAllClientLayersForInvalidation()
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<RenderLayer*>::iterator layerEnd = m_clientLayers.end();
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (HashSet<RenderLayer*>::iterator it = m_clientLayers.begin(); it != layerEnd; ++it)
136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        (*it)->filterNeedsPaintInvalidation();
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client, InvalidationMode mode)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(client);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_clients.isEmpty());
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (mode) {
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case LayoutAndBoundariesInvalidation:
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case BoundariesInvalidation:
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        client->setNeedsBoundariesUpdate();
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
149e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    case PaintInvalidation:
1509e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        client->setShouldDoFullPaintInvalidation(true);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ParentOnlyInvalidation:
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::addClient(RenderObject* client)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(client);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_clients.add(client);
16151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    clearInvalidationMask();
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::removeClient(RenderObject* client)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(client);
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    removeClientFromCache(client, false);
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_clients.remove(client);
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1718abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void RenderSVGResourceContainer::addClientRenderLayer(Node* node)
1728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
1738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(node);
1748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!node->renderer() || !node->renderer()->hasLayer())
1758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return;
1768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_clientLayers.add(toRenderLayerModelObject(node->renderer())->layer());
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    clearInvalidationMask();
1788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
1798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::addClientRenderLayer(RenderLayer* client)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(client);
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_clientLayers.add(client);
18451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    clearInvalidationMask();
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::removeClientRenderLayer(RenderLayer* client)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(client);
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_clientLayers.remove(client);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
193f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)void RenderSVGResourceContainer::invalidateCacheAndMarkForLayout(SubtreeLayoutScope* layoutScope)
194f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
195f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (selfNeedsLayout())
196f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        return;
197f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
1985d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    setNeedsLayoutAndFullPaintInvalidation(MarkContainingBlockChain, layoutScope);
199f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
200f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    if (everHadLayout())
201f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        removeAllClientsFromCache();
202f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
203f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderSVGResourceContainer::registerResource()
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!extensions.hasPendingResource(m_id)) {
208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extensions.addResource(m_id, this);
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    OwnPtrWillBeRawPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions.removePendingResource(m_id));
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Cache us with the new id.
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    extensions.addResource(m_id, this);
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Update cached resources of pending clients.
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT((*it)->hasPendingResources());
221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extensions.clearHasPendingResourcesIfPossible(*it);
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderObject* renderer = (*it)->renderer();
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!renderer)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
22510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch
22610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        StyleDifference diff;
22710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        diff.setNeedsFullLayout();
22810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        SVGResourcesCache::clientStyleChanged(renderer, diff, renderer->style());
2295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        renderer->setNeedsLayoutAndFullPaintInvalidation();
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
233d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static bool shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
234d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
235d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ASSERT(object);
236d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
237d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // This method should only be called for RenderObjects that deal with text rendering. Cmp. RenderObject.h's is*() methods.
238d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    ASSERT(object->isSVGText() || object->isSVGTextPath() || object->isSVGInline());
239d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
240d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // In text drawing, the scaling part of the graphics context CTM is removed, compare SVGInlineTextBox::paintTextWithShadows.
241d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // So, we use that scaling factor here, too, and then push it down to pattern or gradient space
242d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    // in order to keep the pattern or gradient correctly scaled.
243d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(object);
244d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (scalingFactor == 1)
245d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return false;
246d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    resourceTransform.scale(scalingFactor);
247d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return true;
248d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
249d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
250197021e6b966cfb06891637935ef33fff06433d1Ben MurdochAffineTransform RenderSVGResourceContainer::computeResourceSpaceTransform(RenderObject* object, const AffineTransform& baseTransform, const SVGRenderStyle& svgStyle, unsigned short resourceMode)
2516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{
2526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    AffineTransform computedSpaceTransform = baseTransform;
2536f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (resourceMode & ApplyToTextMode) {
2546f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // Depending on the font scaling factor, we may need to apply an
2556f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // additional transform (scale-factor) the paintserver, since text
2566f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // painting removes the scale factor from the context. (See
2576f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // SVGInlineTextBox::paintTextWithShadows.)
2586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        AffineTransform additionalTextTransformation;
2596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (shouldTransformOnTextPainting(object, additionalTextTransformation))
2606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            computedSpaceTransform = additionalTextTransformation * computedSpaceTransform;
2616f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
2626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    if (resourceMode & ApplyToStrokeMode) {
2636f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        // Non-scaling stroke needs to reset the transform back to the host transform.
264197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (svgStyle.vectorEffect() == VE_NON_SCALING_STROKE)
2656f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            computedSpaceTransform = transformOnNonScalingStroke(object, computedSpaceTransform);
2666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
2676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    return computedSpaceTransform;
2686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch}
2696f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: This does not belong here.
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!object->isSVGShape())
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return resourceTransform;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
276591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    SVGGraphicsElement* element = toSVGGraphicsElement(object->node());
27751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    AffineTransform transform = element->getScreenCTM(SVGGraphicsElement::DisallowStyleUpdate);
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    transform *= resourceTransform;
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return transform;
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
283