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