This source file includes following definitions.
- addResourcesFromRenderObject
- removeResourcesFromRenderObject
- resourcesCacheFromRenderObject
- cachedResourcesForRenderObject
- clientLayoutChanged
- rendererCanHaveResources
- clientStyleChanged
- clientWasAddedToTree
- clientWillBeRemovedFromTree
- clientDestroyed
- resourceDestroyed
#include "config.h"
#include "core/rendering/svg/SVGResourcesCache.h"
#include "HTMLNames.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCycleSolver.h"
#include "core/svg/SVGDocumentExtensions.h"
namespace WebCore {
SVGResourcesCache::SVGResourcesCache()
{
}
SVGResourcesCache::~SVGResourcesCache()
{
}
void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
ASSERT(!m_cache.contains(object));
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
OwnPtr<SVGResources> newResources = SVGResources::buildResources(object, svgStyle);
if (!newResources)
return;
SVGResources* resources = m_cache.set(object, newResources.release()).storedValue->value.get();
SVGResourcesCycleSolver solver(object, resources);
solver.resolveCycles();
HashSet<RenderSVGResourceContainer*> resourceSet;
resources->buildSetOfResources(resourceSet);
HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end();
for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it)
(*it)->addClient(object);
}
void SVGResourcesCache::removeResourcesFromRenderObject(RenderObject* object)
{
OwnPtr<SVGResources> resources = m_cache.take(object);
if (!resources)
return;
HashSet<RenderSVGResourceContainer*> resourceSet;
resources->buildSetOfResources(resourceSet);
HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end();
for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it)
(*it)->removeClient(object);
}
static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObject* renderer)
{
Document& document = renderer->document();
SVGDocumentExtensions& extensions = document.accessSVGExtensions();
SVGResourcesCache* cache = extensions.resourcesCache();
ASSERT(cache);
return cache;
}
SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(const RenderObject* renderer)
{
ASSERT(renderer);
return resourcesCacheFromRenderObject(renderer)->m_cache.get(renderer);
}
void SVGResourcesCache::clientLayoutChanged(RenderObject* object)
{
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
if (!resources)
return;
if (object->selfNeedsLayout() || resources->filter())
resources->removeClientFromCache(object);
}
static inline bool rendererCanHaveResources(RenderObject* renderer)
{
ASSERT(renderer);
return renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGInlineText();
}
void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle)
{
ASSERT(renderer);
ASSERT(renderer->node());
ASSERT(renderer->node()->isSVGElement());
if (diff == StyleDifferenceEqual || !renderer->parent())
return;
if (renderer->isSVGResourceFilterPrimitive() && (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintIfTextOrColorChange))
return;
if (rendererCanHaveResources(renderer)) {
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->removeResourcesFromRenderObject(renderer);
cache->addResourcesFromRenderObject(renderer, newStyle);
}
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
}
void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const RenderStyle* newStyle)
{
if (!renderer->node())
return;
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
if (!rendererCanHaveResources(renderer))
return;
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->addResourcesFromRenderObject(renderer, newStyle);
}
void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject* renderer)
{
if (!renderer->node())
return;
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
if (!rendererCanHaveResources(renderer))
return;
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->removeResourcesFromRenderObject(renderer);
}
void SVGResourcesCache::clientDestroyed(RenderObject* renderer)
{
ASSERT(renderer);
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (resources)
resources->removeClientFromCache(renderer);
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->removeResourcesFromRenderObject(renderer);
}
void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource)
{
ASSERT(resource);
SVGResourcesCache* cache = resourcesCacheFromRenderObject(resource);
cache->removeResourcesFromRenderObject(resource);
CacheMap::iterator end = cache->m_cache.end();
for (CacheMap::iterator it = cache->m_cache.begin(); it != end; ++it) {
it->value->resourceDestroyed(resource);
Element* resourceElement = resource->element();
Element* clientElement = toElement(it->key->node());
SVGDocumentExtensions& extensions = clientElement->document().accessSVGExtensions();
extensions.addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
}
}
}