1/* 2 * Copyright (C) 2010 University of Szeged 3 * Copyright (C) 2010 Zoltan Herczeg 4 * Copyright (C) 2011 Renata Hodovan (reni@webkit.org) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "config.h" 29 30#if ENABLE(FILTERS) 31#include "RenderSVGResourceFilterPrimitive.h" 32 33#include "SVGFEImage.h" 34#include "SVGFilterPrimitiveStandardAttributes.h" 35#include "SVGNames.h" 36 37namespace WebCore { 38 39RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes& filterPrimitiveElement, PassRef<RenderStyle> style) 40 : RenderSVGHiddenContainer(filterPrimitiveElement, WTF::move(style)) 41{ 42} 43 44SVGFilterPrimitiveStandardAttributes& RenderSVGResourceFilterPrimitive::filterPrimitiveElement() const 45{ 46 return static_cast<SVGFilterPrimitiveStandardAttributes&>(RenderSVGHiddenContainer::element()); 47} 48 49void RenderSVGResourceFilterPrimitive::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 50{ 51 RenderSVGHiddenContainer::styleDidChange(diff, oldStyle); 52 53 RenderObject* filter = parent(); 54 if (!filter) 55 return; 56 ASSERT(filter->isSVGResourceFilter()); 57 58 if (diff == StyleDifferenceEqual || !oldStyle) 59 return; 60 61 const SVGRenderStyle& newStyle = style().svgStyle(); 62 if (filterPrimitiveElement().hasTagName(SVGNames::feFloodTag)) { 63 if (newStyle.floodColor() != oldStyle->svgStyle().floodColor()) 64 toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr); 65 if (newStyle.floodOpacity() != oldStyle->svgStyle().floodOpacity()) 66 toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr); 67 } else if (filterPrimitiveElement().hasTagName(SVGNames::feDiffuseLightingTag) || filterPrimitiveElement().hasTagName(SVGNames::feSpecularLightingTag)) { 68 if (newStyle.lightingColor() != oldStyle->svgStyle().lightingColor()) 69 toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr); 70 } 71} 72 73FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect) 74{ 75 SVGFilter* filter = toSVGFilter(&(effect->filter())); 76 ASSERT(filter); 77 78 // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. 79 FloatRect subregion; 80 if (unsigned numberOfInputEffects = effect->inputEffects().size()) { 81 subregion = determineFilterPrimitiveSubregion(effect->inputEffect(0)); 82 for (unsigned i = 1; i < numberOfInputEffects; ++i) 83 subregion.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i))); 84 } else 85 subregion = filter->filterRegionInUserSpace(); 86 87 // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. 88 if (effect->filterEffectType() == FilterEffectTypeTile) 89 subregion = filter->filterRegionInUserSpace(); 90 91 FloatRect effectBoundaries = effect->effectBoundaries(); 92 if (effect->hasX()) 93 subregion.setX(effectBoundaries.x()); 94 if (effect->hasY()) 95 subregion.setY(effectBoundaries.y()); 96 if (effect->hasWidth()) 97 subregion.setWidth(effectBoundaries.width()); 98 if (effect->hasHeight()) 99 subregion.setHeight(effectBoundaries.height()); 100 101 effect->setFilterPrimitiveSubregion(subregion); 102 103 FloatRect absoluteSubregion = filter->absoluteTransform().mapRect(subregion); 104 FloatSize filterResolution = filter->filterResolution(); 105 absoluteSubregion.scale(filterResolution.width(), filterResolution.height()); 106 107 // Clip every filter effect to the filter region. 108 FloatRect absoluteScaledFilterRegion = filter->filterRegion(); 109 absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height()); 110 absoluteSubregion.intersect(absoluteScaledFilterRegion); 111 112 effect->setMaxEffectRect(absoluteSubregion); 113 return subregion; 114} 115 116} // namespace WebCore 117 118#endif // ENABLE(FILTERS) 119