SVGResourcesCache.cpp [plain text]
#include "config.h"
#include "SVGResourcesCache.h"
#if ENABLE(SVG)
#include "RenderSVGResourceContainer.h"
#include "SVGDocumentExtensions.h"
#include "SVGResources.h"
#include "SVGResourcesCycleSolver.h"
namespace WebCore {
SVGResourcesCache::SVGResourcesCache()
{
}
SVGResourcesCache::~SVGResourcesCache()
{
deleteAllValues(m_cache);
}
void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
ASSERT(!m_cache.contains(object));
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
SVGResources* resources = new SVGResources;
if (!resources->buildCachedResources(object, svgStyle)) {
delete resources;
return;
}
m_cache.set(object, resources);
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)
{
if (!m_cache.contains(object))
return;
SVGResources* resources = m_cache.get(object);
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);
delete m_cache.take(object);
}
static inline SVGResourcesCache* resourcesCacheFromRenderObject(RenderObject* renderer)
{
Document* document = renderer->document();
ASSERT(document);
SVGDocumentExtensions* extensions = document->accessSVGExtensions();
ASSERT(extensions);
SVGResourcesCache* cache = extensions->resourcesCache();
ASSERT(cache);
return cache;
}
SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(RenderObject* renderer)
{
ASSERT(renderer);
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
if (!cache->m_cache.contains(renderer))
return 0;
return cache->m_cache.get(renderer);
}
void SVGResourcesCache::clientLayoutChanged(RenderObject* object)
{
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
if (!resources)
return;
resources->removeClientFromCache(object);
}
void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle)
{
ASSERT(renderer);
if (diff == StyleDifferenceEqual)
return;
if (renderer->isSVGResourceFilterPrimitive() && diff == StyleDifferenceRepaint)
return;
clientUpdatedFromElement(renderer, newStyle);
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
}
void SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle)
{
ASSERT(renderer);
ASSERT(renderer->parent());
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->removeResourcesFromRenderObject(renderer);
cache->addResourcesFromRenderObject(renderer, newStyle);
}
void SVGResourcesCache::clientDestroyed(RenderObject* renderer)
{
ASSERT(renderer);
SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
cache->removeResourcesFromRenderObject(renderer);
}
void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource)
{
ASSERT(resource);
SVGResourcesCache* cache = resourcesCacheFromRenderObject(resource);
cache->removeResourcesFromRenderObject(resource);
HashMap<RenderObject*, SVGResources*>::iterator end = cache->m_cache.end();
for (HashMap<RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it)
it->second->resourceDestroyed(resource);
}
}
#endif