15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
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"
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/graphics/filters/SVGFilterBuilder.h"
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/SourceAlpha.h"
24a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/SourceGraphic.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGFilterBuilder::SVGFilterBuilder(PassRefPtr<FilterEffect> sourceGraphic, PassRefPtr<FilterEffect> sourceAlpha)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_builtinEffects.add(SourceGraphic::effectName(), sourceGraphic);
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_builtinEffects.add(SourceAlpha::effectName(), sourceAlpha);
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addBuiltinEffects();
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGFilterBuilder::add(const AtomicString& id, PassRefPtr<FilterEffect> effect)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (id.isEmpty()) {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastEffect = effect;
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_builtinEffects.contains(id))
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastEffect = effect;
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_namedEffects.set(id, m_lastEffect);
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FilterEffect* SVGFilterBuilder::getEffectById(const AtomicString& id) const
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (id.isEmpty()) {
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_lastEffect)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return m_lastEffect.get();
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return m_builtinEffects.get(SourceGraphic::effectName());
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_builtinEffects.contains(id))
5981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return m_builtinEffects.get(id);
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    return m_namedEffects.get(id);
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> prpEffect, RenderObject* object)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<FilterEffect> effect = prpEffect;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The effect must be a newly created filter effect.
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_effectReferences.contains(effect));
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(object && !m_effectRenderer.contains(object));
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_effectReferences.add(effect, FilterEffectSet());
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned numberOfInputEffects = effect->inputEffects().size();
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // It is not possible to add the same value to a set twice.
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0; i < numberOfInputEffects; ++i)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        effectReferences(effect->inputEffect(i)).add(effect.get());
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_effectRenderer.add(object, effect.get());
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGFilterBuilder::clearEffects()
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_lastEffect = nullptr;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_namedEffects.clear();
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_effectReferences.clear();
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_effectRenderer.clear();
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    addBuiltinEffects();
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void SVGFilterBuilder::clearResultsRecursive(FilterEffect* effect)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
92f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    if (!effect->hasResult() && !effect->hasImageFilter())
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    effect->clearResult();
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<FilterEffect*>& effectReferences = this->effectReferences(effect);
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HashSet<FilterEffect*>::iterator end = effectReferences.end();
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (HashSet<FilterEffect*>::iterator it = effectReferences.begin(); it != end; ++it)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)         clearResultsRecursive(*it);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
104