Bug 964200 (Part 3 main) - Implement Filter Effects Module feDropShadow filter. r=mstange

--HG--
rename : content/svg/content/src/SVGFEGaussianBlurElement.cpp => content/svg/content/src/SVGFEDropShadowElement.cpp
rename : content/svg/content/src/SVGFEGaussianBlurElement.h => content/svg/content/src/SVGFEDropShadowElement.h
rename : dom/webidl/SVGFEGaussianBlurElement.webidl => dom/webidl/SVGFEDropShadowElement.webidl
This commit is contained in:
Robert Longson 2014-02-05 16:46:47 +00:00
parent 5dbc0265fb
commit 99cbdf39af
13 changed files with 485 additions and 23 deletions

View File

@ -0,0 +1,181 @@
/* a*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEDropShadowElement.h"
#include "mozilla/dom/SVGFEDropShadowElementBinding.h"
#include "nsSVGFilterInstance.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEDropShadow)
using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
JSObject*
SVGFEDropShadowElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SVGFEDropShadowElementBinding::Wrap(aCx, aScope, this);
}
nsSVGElement::NumberInfo SVGFEDropShadowElement::sNumberInfo[2] =
{
{ &nsGkAtoms::dx, 2, false },
{ &nsGkAtoms::dy, 2, false }
};
nsSVGElement::NumberPairInfo SVGFEDropShadowElement::sNumberPairInfo[1] =
{
{ &nsGkAtoms::stdDeviation, 2, 2 }
};
nsSVGElement::StringInfo SVGFEDropShadowElement::sStringInfo[2] =
{
{ &nsGkAtoms::result, kNameSpaceID_None, true },
{ &nsGkAtoms::in, kNameSpaceID_None, true }
};
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEDropShadowElement)
//----------------------------------------------------------------------
already_AddRefed<SVGAnimatedString>
SVGFEDropShadowElement::In1()
{
return mStringAttributes[IN1].ToDOMAnimatedString(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEDropShadowElement::Dx()
{
return mNumberAttributes[DX].ToDOMAnimatedNumber(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEDropShadowElement::Dy()
{
return mNumberAttributes[DY].ToDOMAnimatedNumber(this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEDropShadowElement::StdDeviationX()
{
return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(nsSVGNumberPair::eFirst, this);
}
already_AddRefed<SVGAnimatedNumber>
SVGFEDropShadowElement::StdDeviationY()
{
return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(nsSVGNumberPair::eSecond, this);
}
void
SVGFEDropShadowElement::SetStdDeviation(float stdDeviationX, float stdDeviationY)
{
mNumberPairAttributes[STD_DEV].SetBaseValues(stdDeviationX, stdDeviationY, this);
}
FilterPrimitiveDescription
SVGFEDropShadowElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
const IntRect& aFilterSubregion,
const nsTArray<bool>& aInputsAreTainted,
nsTArray<RefPtr<SourceSurface>>& aInputImages)
{
float stdX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
&mNumberPairAttributes[STD_DEV],
nsSVGNumberPair::eFirst);
float stdY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
&mNumberPairAttributes[STD_DEV],
nsSVGNumberPair::eSecond);
if (stdX < 0 || stdY < 0) {
return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
IntPoint offset(int32_t(aInstance->GetPrimitiveNumber(
SVGContentUtils::X, &mNumberAttributes[DX])),
int32_t(aInstance->GetPrimitiveNumber(
SVGContentUtils::Y, &mNumberAttributes[DY])));
FilterPrimitiveDescription descr(FilterPrimitiveDescription::eDropShadow);
descr.Attributes().Set(eDropShadowStdDeviation, Size(stdX, stdY));
descr.Attributes().Set(eDropShadowOffset, offset);
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
nsStyleContext* style = frame->StyleContext();
nscolor floodColor = style->StyleSVGReset()->mFloodColor;
float floodOpacity = style->StyleSVGReset()->mFloodOpacity;
Color color(NS_GET_R(floodColor) / 255.0,
NS_GET_G(floodColor) / 255.0,
NS_GET_B(floodColor) / 255.0,
NS_GET_A(floodColor) / 255.0 * floodOpacity);
descr.Attributes().Set(eDropShadowColor, color);
} else {
descr.Attributes().Set(eDropShadowColor, Color());
}
return descr;
}
bool
SVGFEDropShadowElement::AttributeAffectsRendering(int32_t aNameSpaceID,
nsIAtom* aAttribute) const
{
return SVGFEDropShadowElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
(aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::in ||
aAttribute == nsGkAtoms::stdDeviation ||
aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy));
}
void
SVGFEDropShadowElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
//----------------------------------------------------------------------
// nsIContent methods
NS_IMETHODIMP_(bool)
SVGFEDropShadowElement::IsAttributeMapped(const nsIAtom* name) const
{
static const MappedAttributeEntry* const map[] = {
sFEFloodMap
};
return FindAttributeDependence(name, map) ||
SVGFEDropShadowElementBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
SVGFEDropShadowElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
ArrayLength(sNumberInfo));
}
nsSVGElement::NumberPairAttributesInfo
SVGFEDropShadowElement::GetNumberPairInfo()
{
return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
ArrayLength(sNumberPairInfo));
}
nsSVGElement::StringAttributesInfo
SVGFEDropShadowElement::GetStringInfo()
{
return StringAttributesInfo(mStringAttributes, sStringInfo,
ArrayLength(sStringInfo));
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,79 @@
/* a*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGFEDropShadowElement_h
#define mozilla_dom_SVGFEDropShadowElement_h
#include "nsSVGFilters.h"
#include "nsSVGNumber2.h"
#include "nsSVGNumberPair.h"
#include "nsSVGString.h"
nsresult NS_NewSVGFEDropShadowElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
namespace dom {
typedef nsSVGFE SVGFEDropShadowElementBase;
class SVGFEDropShadowElement : public SVGFEDropShadowElementBase
{
friend nsresult (::NS_NewSVGFEDropShadowElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
protected:
SVGFEDropShadowElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGFEDropShadowElementBase(aNodeInfo)
{
}
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
public:
virtual FilterPrimitiveDescription
GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
const IntRect& aFilterSubregion,
const nsTArray<bool>& aInputsAreTainted,
nsTArray<mozilla::RefPtr<SourceSurface>>& aInputImages) MOZ_OVERRIDE;
virtual bool AttributeAffectsRendering(
int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo >& aSources) MOZ_OVERRIDE;
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL
already_AddRefed<SVGAnimatedString> In1();
already_AddRefed<SVGAnimatedNumber> Dx();
already_AddRefed<SVGAnimatedNumber> Dy();
already_AddRefed<SVGAnimatedNumber> StdDeviationX();
already_AddRefed<SVGAnimatedNumber> StdDeviationY();
void SetStdDeviation(float stdDeviationX, float stdDeviationY);
protected:
virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
enum { DX, DY };
nsSVGNumber2 mNumberAttributes[2];
static NumberInfo sNumberInfo[2];
enum { STD_DEV };
nsSVGNumberPair mNumberPairAttributes[1];
static NumberPairInfo sNumberPairInfo[1];
enum { RESULT, IN1 };
nsSVGString mStringAttributes[2];
static StringInfo sStringInfo[2];
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGFEDropShadowElement_h

View File

@ -63,8 +63,6 @@ SVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviatio
mNumberPairAttributes[STD_DEV].SetBaseValues(stdDeviationX, stdDeviationY, this);
}
static const float kMaxStdDeviation = 500;
FilterPrimitiveDescription
SVGFEGaussianBlurElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
const IntRect& aFilterSubregion,
@ -81,8 +79,6 @@ SVGFEGaussianBlurElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance
return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
}
stdX = std::min(stdX, kMaxStdDeviation);
stdY = std::min(stdY, kMaxStdDeviation);
FilterPrimitiveDescription descr(FilterPrimitiveDescription::eGaussianBlur);
descr.Attributes().Set(eGaussianBlurStdDeviation, Size(stdX, stdY));
return descr;

View File

@ -45,6 +45,7 @@ SVG_TAG(feConvolveMatrix, FEConvolveMatrix)
SVG_TAG(feDiffuseLighting, FEDiffuseLighting)
SVG_TAG(feDisplacementMap, FEDisplacementMap)
SVG_TAG(feDistantLight, FEDistantLight)
SVG_TAG(feDropShadow, FEDropShadow)
SVG_TAG(feFlood, FEFlood)
SVG_TAG(feFuncA, FEFuncA)
SVG_TAG(feFuncB, FEFuncB)

View File

@ -45,6 +45,7 @@ EXPORTS.mozilla.dom += [
'SVGFEDiffuseLightingElement.h',
'SVGFEDisplacementMapElement.h',
'SVGFEDistantLightElement.h',
'SVGFEDropShadowElement.h',
'SVGFEFloodElement.h',
'SVGFEGaussianBlurElement.h',
'SVGFEImageElement.h',
@ -168,6 +169,7 @@ UNIFIED_SOURCES += [
'SVGFEDiffuseLightingElement.cpp',
'SVGFEDisplacementMapElement.cpp',
'SVGFEDistantLightElement.cpp',
'SVGFEDropShadowElement.cpp',
'SVGFEFloodElement.cpp',
'SVGFEGaussianBlurElement.cpp',
'SVGFEImageElement.cpp',

View File

@ -54,6 +54,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=589640
<feDiffuseLighting id="feDiffuseLighting" />
<feDisplacementMap id="feDisplacementMap" />
<feDistantLight id="feDistantLight" />
<feDropShadow id="feDropShadow" />
<feFlood id="feFlood" />
<feFuncA id="feFuncA" />
<feFuncB id="feFuncB" />

View File

@ -0,0 +1,23 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/SVG2/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface SVGFEDropShadowElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber dx;
readonly attribute SVGAnimatedNumber dy;
readonly attribute SVGAnimatedNumber stdDeviationX;
readonly attribute SVGAnimatedNumber stdDeviationY;
void setStdDeviation(float stdDeviationX, float stdDeviationY);
};
SVGFEDropShadowElement implements SVGFilterPrimitiveStandardAttributes;

View File

@ -326,6 +326,7 @@ WEBIDL_FILES = [
'SVGFEDiffuseLightingElement.webidl',
'SVGFEDisplacementMapElement.webidl',
'SVGFEDistantLightElement.webidl',
'SVGFEDropShadowElement.webidl',
'SVGFEFloodElement.webidl',
'SVGFEFuncAElement.webidl',
'SVGFEFuncBElement.webidl',

View File

@ -95,6 +95,8 @@ namespace gfx {
// Some convenience FilterNode creation functions.
static const float kMaxStdDeviation = 500;
namespace FilterWrappers {
static TemporaryRef<FilterNode>
@ -161,6 +163,28 @@ namespace FilterWrappers {
return filter;
}
static TemporaryRef<FilterNode>
GaussianBlur(DrawTarget* aDT, FilterNode* aInputFilter, const Size& aStdDeviation)
{
float stdX = float(std::min(aStdDeviation.width, kMaxStdDeviation));
float stdY = float(std::min(aStdDeviation.height, kMaxStdDeviation));
if (stdX == stdY) {
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::GAUSSIAN_BLUR);
filter->SetAttribute(ATT_GAUSSIAN_BLUR_STD_DEVIATION, stdX);
filter->SetInput(IN_GAUSSIAN_BLUR_IN, aInputFilter);
return filter;
}
RefPtr<FilterNode> filterH = aDT->CreateFilter(FilterType::DIRECTIONAL_BLUR);
RefPtr<FilterNode> filterV = aDT->CreateFilter(FilterType::DIRECTIONAL_BLUR);
filterH->SetAttribute(ATT_DIRECTIONAL_BLUR_DIRECTION, (uint32_t)BLUR_DIRECTION_X);
filterH->SetAttribute(ATT_DIRECTIONAL_BLUR_STD_DEVIATION, stdX);
filterV->SetAttribute(ATT_DIRECTIONAL_BLUR_DIRECTION, (uint32_t)BLUR_DIRECTION_Y);
filterV->SetAttribute(ATT_DIRECTIONAL_BLUR_STD_DEVIATION, stdY);
filterH->SetInput(IN_DIRECTIONAL_BLUR_IN, aInputFilter);
filterV->SetInput(IN_DIRECTIONAL_BLUR_IN, filterH);
return filterV;
}
static TemporaryRef<FilterNode>
Clear(DrawTarget* aDT)
{
@ -815,22 +839,37 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
case FilterPrimitiveDescription::eGaussianBlur:
{
Size stdDeviation = atts.GetSize(eGaussianBlurStdDeviation);
if (stdDeviation.width == stdDeviation.height) {
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::GAUSSIAN_BLUR);
filter->SetAttribute(ATT_GAUSSIAN_BLUR_STD_DEVIATION, float(stdDeviation.width));
filter->SetInput(IN_GAUSSIAN_BLUR_IN, aSources[0]);
return filter;
return FilterWrappers::GaussianBlur(aDT, aSources[0],
atts.GetSize(eGaussianBlurStdDeviation));
}
case FilterPrimitiveDescription::eDropShadow:
{
RefPtr<FilterNode> alpha = FilterWrappers::ToAlpha(aDT, aSources[0]);
RefPtr<FilterNode> blur = FilterWrappers::GaussianBlur(aDT, alpha,
atts.GetSize(eDropShadowStdDeviation));
RefPtr<FilterNode> offsetBlur = FilterWrappers::Offset(aDT, blur,
atts.GetIntPoint(eDropShadowOffset));
RefPtr<FilterNode> flood = aDT->CreateFilter(FilterType::FLOOD);
Color color = atts.GetColor(eDropShadowColor);
if (aDescription.InputColorSpace(0) == LINEAR_RGB) {
color = Color(gsRGBToLinearRGBMap[uint8_t(color.r * 255)],
gsRGBToLinearRGBMap[uint8_t(color.g * 255)],
gsRGBToLinearRGBMap[uint8_t(color.b * 255)],
color.a);
}
RefPtr<FilterNode> filterH = aDT->CreateFilter(FilterType::DIRECTIONAL_BLUR);
RefPtr<FilterNode> filterV = aDT->CreateFilter(FilterType::DIRECTIONAL_BLUR);
filterH->SetAttribute(ATT_DIRECTIONAL_BLUR_DIRECTION, (uint32_t)BLUR_DIRECTION_X);
filterH->SetAttribute(ATT_DIRECTIONAL_BLUR_STD_DEVIATION, float(stdDeviation.width));
filterV->SetAttribute(ATT_DIRECTIONAL_BLUR_DIRECTION, (uint32_t)BLUR_DIRECTION_Y);
filterV->SetAttribute(ATT_DIRECTIONAL_BLUR_STD_DEVIATION, float(stdDeviation.height));
filterH->SetInput(IN_DIRECTIONAL_BLUR_IN, aSources[0]);
filterV->SetInput(IN_DIRECTIONAL_BLUR_IN, filterH);
return filterV;
flood->SetAttribute(ATT_FLOOD_COLOR, color);
RefPtr<FilterNode> composite = aDT->CreateFilter(FilterType::COMPOSITE);
composite->SetAttribute(ATT_COMPOSITE_OPERATOR, (uint32_t)COMPOSITE_OPERATOR_IN);
composite->SetInput(IN_COMPOSITE_IN_START, offsetBlur);
composite->SetInput(IN_COMPOSITE_IN_START + 1, flood);
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::COMPOSITE);
filter->SetAttribute(ATT_COMPOSITE_OPERATOR, (uint32_t)COMPOSITE_OPERATOR_OVER);
filter->SetInput(IN_COMPOSITE_IN_START, composite);
filter->SetInput(IN_COMPOSITE_IN_START + 1, aSources[0]);
return filter;
}
case FilterPrimitiveDescription::eDiffuseLighting:
@ -1127,11 +1166,9 @@ UnionOfRegions(const nsTArray<nsIntRegion>& aRegions)
}
static int32_t
InflateSizeForBlurStdDev(double aStdDev)
InflateSizeForBlurStdDev(float aStdDev)
{
double size = aStdDev * (3 * sqrt(2 * M_PI) / 4) * 1.5;
static const double max = 1024;
size = std::min(size, max);
double size = std::min(aStdDev, kMaxStdDeviation) * (3 * sqrt(2 * M_PI) / 4) * 1.5;
return uint32_t(floor(size + 0.5));
}
@ -1200,6 +1237,18 @@ ResultChangeRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
return aInputChangeRegions[0].Inflated(nsIntMargin(dy, dx, dy, dx));
}
case FilterPrimitiveDescription::eDropShadow:
{
IntPoint offset = atts.GetIntPoint(eDropShadowOffset);
nsIntRegion offsetRegion = aInputChangeRegions[0].MovedBy(offset.x, offset.y);
Size stdDeviation = atts.GetSize(eDropShadowStdDeviation);
int32_t dx = InflateSizeForBlurStdDev(stdDeviation.width);
int32_t dy = InflateSizeForBlurStdDev(stdDeviation.height);
nsIntRegion blurRegion = offsetRegion.Inflated(nsIntMargin(dy, dx, dy, dx));
blurRegion.Or(blurRegion, aInputChangeRegions[0]);
return blurRegion;
}
case FilterPrimitiveDescription::eDiffuseLighting:
case FilterPrimitiveDescription::eSpecularLighting:
{
@ -1418,6 +1467,19 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
return aResultNeededRegion.Inflated(nsIntMargin(dy, dx, dy, dx));
}
case FilterPrimitiveDescription::eDropShadow:
{
IntPoint offset = atts.GetIntPoint(eDropShadowOffset);
nsIntRegion offsetRegion =
aResultNeededRegion.MovedBy(-nsIntPoint(offset.x, offset.y));
Size stdDeviation = atts.GetSize(eDropShadowStdDeviation);
int32_t dx = InflateSizeForBlurStdDev(stdDeviation.width);
int32_t dy = InflateSizeForBlurStdDev(stdDeviation.height);
nsIntRegion blurRegion = offsetRegion.Inflated(nsIntMargin(dy, dx, dy, dx));
blurRegion.Or(blurRegion, aResultNeededRegion);
return blurRegion;
}
case FilterPrimitiveDescription::eDiffuseLighting:
case FilterPrimitiveDescription::eSpecularLighting:
{

View File

@ -100,6 +100,9 @@ enum AttributeName {
eConvolveMatrixKernelUnitLength,
eConvolveMatrixPreserveAlpha,
eOffsetOffset,
eDropShadowStdDeviation,
eDropShadowOffset,
eDropShadowColor,
eDisplacementMapScale,
eDisplacementMapXChannel,
eDisplacementMapYChannel,
@ -231,6 +234,7 @@ public:
eMerge,
eImage,
eGaussianBlur,
eDropShadow,
eDiffuseLighting,
eSpecularLighting
};

View File

@ -4989,6 +4989,7 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement,
SIMPLE_SVG_CREATE(feConvolveMatrix, NS_NewSVGFELeafFrame),
SIMPLE_SVG_CREATE(feDiffuseLighting, NS_NewSVGFEContainerFrame),
SIMPLE_SVG_CREATE(feDisplacementMap, NS_NewSVGFELeafFrame),
SIMPLE_SVG_CREATE(feDropShadow, NS_NewSVGFELeafFrame),
SIMPLE_SVG_CREATE(feFlood, NS_NewSVGFELeafFrame),
SIMPLE_SVG_CREATE(feGaussianBlur, NS_NewSVGFELeafFrame),
SIMPLE_SVG_CREATE(feImage, NS_NewSVGFEImageFrame),

View File

@ -0,0 +1,68 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<title>Reference for Filter Effects Module Level 1 feDropShadow</title>
<defs>
<filter id="dropShadow1">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="2" dy="2" result="offsetblur"/>
<feFlood flood-color="green"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="dropShadow2">
<feGaussianBlur in="SourceAlpha" stdDeviation="5"/>
<feOffset dx="-2" dy="-5" result="offsetblur"/>
<feFlood flood-color="green"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="dropShadow3">
<feGaussianBlur in="SourceAlpha" stdDeviation="2 5"/>
<feOffset dx="5" dy="5" result="offsetblur"/>
<feFlood flood-color="green" flood-opacity="0.5"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="dropShadow4" color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceAlpha" stdDeviation="5"/>
<feOffset dx="5" dy="5" result="offsetblur"/>
<feFlood flood-color="green"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<filter id="dropShadow5">
<feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
<feOffset dx="2" dy="2" result="offsetblur"/>
<feFlood flood-color="green"/>
<feComposite in2="offsetblur" operator="in"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceAlpha"/>
</feMerge>
</filter>
</defs>
<g fill="yellow" transform="translate(10,10)">
<circle cx="75" cy="75" r="70" filter="url(#dropShadow1)" />
<circle cx="250" cy="75" r="70" filter="url(#dropShadow2)" />
<circle cx="425" cy="75" r="70" filter="url(#dropShadow3)" />
<circle cx="600" cy="75" r="70" filter="url(#dropShadow4)" />
<circle cx="75" cy="250" r="70" filter="url(#dropShadow5)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,43 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<title>Testcase for Filter Effects Module Level 1 feDropShadow</title>
<defs>
<!-- check default values -->
<filter id="dropShadow1">
<feDropShadow flood-color="green"/>
</filter>
<!-- check negative dx, dy -->
<filter id="dropShadow2">
<feDropShadow stdDeviation="5" dx="-2" dy="-5" flood-color="green"/>
</filter>
<!-- check flood-opacity and non-default values -->
<filter id="dropShadow3">
<feDropShadow stdDeviation="2 5" dx="5" dy="5" flood-color="green" flood-opacity="0.5"/>
</filter>
<!-- check sRGB -->
<filter id="dropShadow4" color-interpolation-filters="sRGB">
<feDropShadow stdDeviation="5" dx="5" dy="5" flood-color="green"/>
</filter>
<!-- check sourceAlpha input -->
<filter id="dropShadow5">
<feDropShadow in="SourceAlpha" flood-color="green"/>
</filter>
<!-- check negative stdDeviation (should not display anything) -->
<filter id="dropShadow6">
<feDropShadow stdDeviation="-2" flood-color="green"/>
</filter>
</defs>
<g fill="yellow" transform="translate(10,10)">
<circle cx="75" cy="75" r="70" filter="url(#dropShadow1)" />
<circle cx="250" cy="75" r="70" filter="url(#dropShadow2)" />
<circle cx="425" cy="75" r="70" filter="url(#dropShadow3)" />
<circle cx="600" cy="75" r="70" filter="url(#dropShadow4)" />
<circle cx="75" cy="250" r="70" filter="url(#dropShadow5)" />
<circle cx="250" cy="250" r="70" filter="url(#dropShadow6)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB