Bug 375846 - implement feConvolveMatrix filter primitive. r=longsonr, sr=roc

This commit is contained in:
tor@cs.brown.edu 2007-06-27 12:02:58 -07:00
Родитель 46a7394eca
Коммит 3972c28dd8
11 изменённых файлов: 931 добавлений и 5 удалений

Просмотреть файл

@ -919,6 +919,7 @@ GK_ATOM(arithmetic, "arithmetic")
GK_ATOM(atop, "atop")
GK_ATOM(baseFrequency, "baseFrequency")
GK_ATOM(baseline_shift, "baseline-shift")
GK_ATOM(bias, "bias")
GK_ATOM(clip_path, "clip-path")
GK_ATOM(clip_rule, "clip-rule")
GK_ATOM(clipPath, "clipPath")
@ -940,9 +941,12 @@ GK_ATOM(dilate, "dilate")
GK_ATOM(direction, "direction")
GK_ATOM(disable, "disable")
GK_ATOM(discrete, "discrete")
GK_ATOM(divisor, "divisor")
GK_ATOM(dominant_baseline, "dominant-baseline")
GK_ATOM(duplicate, "duplicate")
GK_ATOM(dx, "dx")
GK_ATOM(dy, "dy")
GK_ATOM(edgeMode, "edgeMode")
GK_ATOM(ellipse, "ellipse")
GK_ATOM(erode, "erode")
GK_ATOM(ex, "ex")
@ -1019,6 +1023,8 @@ GK_ATOM(k2, "k2")
GK_ATOM(k3, "k3")
GK_ATOM(k4, "k4")
GK_ATOM(kerning, "kerning")
GK_ATOM(kernelMatrix, "kernelMatrix")
GK_ATOM(kernelUnitLength, "kernelUnitLength")
GK_ATOM(letter_spacing, "letter-spacing")
GK_ATOM(lighten, "lighten")
GK_ATOM(linear, "linear")
@ -1069,6 +1075,7 @@ GK_ATOM(pc, "pc")
GK_ATOM(pointer_events, "pointer-events")
GK_ATOM(points, "points")
GK_ATOM(polyline, "polyline")
GK_ATOM(preserveAlpha, "preserveAlpha")
GK_ATOM(preserveAspectRatio, "preserveAspectRatio")
GK_ATOM(primitiveUnits, "primitiveUnits")
GK_ATOM(pt, "pt")
@ -1116,6 +1123,8 @@ GK_ATOM(svgSwitch, "switch")
GK_ATOM(symbol, "symbol")
GK_ATOM(systemLanguage, "systemLanguage")
GK_ATOM(tableValues, "tableValues")
GK_ATOM(targetX, "targetX")
GK_ATOM(targetY, "targetY")
GK_ATOM(text_anchor, "text-anchor")
GK_ATOM(text_decoration, "text-decoration")
GK_ATOM(text_rendering, "text-rendering")

Просмотреть файл

@ -72,6 +72,7 @@ CPPSRCS = \
nsSVGAElement.cpp \
nsSVGAngle.cpp \
nsSVGAnimatedAngle.cpp \
nsSVGAnimatedBoolean.cpp \
nsSVGAnimatedEnumeration.cpp \
nsSVGAnimatedInteger.cpp \
nsSVGAnimatedLengthList.cpp \

Просмотреть файл

@ -0,0 +1,173 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ----- BEGIN LICENSE BLOCK -----
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#include "nsSVGAnimatedBoolean.h"
#include "nsSVGValue.h"
#include "nsISVGValueUtils.h"
#include "nsDOMError.h"
#include "nsContentUtils.h"
////////////////////////////////////////////////////////////////////////
// nsSVGAnimatedBoolean
class nsSVGAnimatedBoolean : public nsIDOMSVGAnimatedBoolean,
public nsSVGValue
{
protected:
friend nsresult NS_NewSVGAnimatedBoolean(nsIDOMSVGAnimatedBoolean** result,
PRBool aBaseVal);
void Init(PRBool aBaseVal);
public:
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsIDOMSVGAnimatedBoolean interface:
NS_DECL_NSIDOMSVGANIMATEDBOOLEAN
// remainder of nsISVGValue interface:
NS_IMETHOD SetValueString(const nsAString& aValue);
NS_IMETHOD GetValueString(nsAString& aValue);
protected:
PRPackedBool mBaseVal;
};
//----------------------------------------------------------------------
// Implementation
void
nsSVGAnimatedBoolean::Init(PRBool aBaseVal)
{
mBaseVal = aBaseVal;
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGAnimatedBoolean)
NS_IMPL_RELEASE(nsSVGAnimatedBoolean)
NS_INTERFACE_MAP_BEGIN(nsSVGAnimatedBoolean)
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedBoolean)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedBoolean)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsISVGValue methods:
NS_IMETHODIMP
nsSVGAnimatedBoolean::SetValueString(const nsAString& aValue)
{
nsresult rv = NS_OK;
WillModify();
if (aValue.EqualsLiteral("true"))
mBaseVal = PR_TRUE;
else if (aValue.EqualsLiteral("false"))
mBaseVal = PR_FALSE;
else
rv = NS_ERROR_FAILURE;
DidModify();
return rv;
}
NS_IMETHODIMP
nsSVGAnimatedBoolean::GetValueString(nsAString& aValue)
{
aValue.Assign(mBaseVal
? NS_LITERAL_STRING("true")
: NS_LITERAL_STRING("false"));
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMSVGAnimatedBoolean methods:
/* attribute nsIDOMSVGNumber baseVal; */
NS_IMETHODIMP
nsSVGAnimatedBoolean::GetBaseVal(PRBool *aBaseVal)
{
*aBaseVal = mBaseVal;
return NS_OK;
}
/* attribute nsIDOMSVGNumber baseVal; */
NS_IMETHODIMP
nsSVGAnimatedBoolean::SetBaseVal(PRBool aBaseVal)
{
if (mBaseVal != aBaseVal &&
(aBaseVal == PR_TRUE || aBaseVal == PR_FALSE)) {
WillModify();
mBaseVal = aBaseVal;
DidModify();
}
return NS_OK;
}
/* readonly attribute nsIDOMSVGNumber animVal; */
NS_IMETHODIMP
nsSVGAnimatedBoolean::GetAnimVal(PRBool *aAnimVal)
{
*aAnimVal = mBaseVal;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// Exported creation functions
nsresult
NS_NewSVGAnimatedBoolean(nsIDOMSVGAnimatedBoolean** aResult,
PRBool aBaseVal)
{
*aResult = nsnull;
nsSVGAnimatedBoolean* animatedBoolean = new nsSVGAnimatedBoolean();
if (!animatedBoolean) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(animatedBoolean);
animatedBoolean->Init(aBaseVal);
*aResult = (nsIDOMSVGAnimatedBoolean*) animatedBoolean;
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ----- BEGIN LICENSE BLOCK -----
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#ifndef __NS_SVGANIMATEDBOOLEAN_H__
#define __NS_SVGANIMATEDBOOLEAN_H__
#include "nsIDOMSVGAnimatedBoolean.h"
nsresult NS_NewSVGAnimatedBoolean(nsIDOMSVGAnimatedBoolean** result,
PRBool baseVal);
#endif //__NS_SVGANIMATEDBOOLEAN_H__

Просмотреть файл

@ -144,6 +144,8 @@ nsresult
NS_NewSVGFETurbulenceElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
nsresult
NS_NewSVGSwitchElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
nsresult
NS_NewSVGFEConvolveMatrixElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
nsresult
NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
@ -250,8 +252,9 @@ NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
return NS_NewSVGFEFloodElement(aResult, aNodeInfo);
if (name == nsGkAtoms::feTurbulence)
return NS_NewSVGFETurbulenceElement(aResult, aNodeInfo);
if (name == nsGkAtoms::feConvolveMatrix ||
name == nsGkAtoms::feDiffuseLighting ||
if (name == nsGkAtoms::feConvolveMatrix)
return NS_NewSVGFEConvolveMatrixElement(aResult, aNodeInfo);
if (name == nsGkAtoms::feDiffuseLighting ||
name == nsGkAtoms::feDisplacementMap ||
name == nsGkAtoms::feImage ||
name == nsGkAtoms::feSpecularLighting ||

Просмотреть файл

@ -60,6 +60,8 @@
#include "nsIFrame.h"
#include "nsSVGAnimatedInteger.h"
#include "gfxContext.h"
#include "nsSVGAnimatedBoolean.h"
#include "nsSVGLengthList.h"
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
{
@ -248,24 +250,32 @@ public:
nsresult AcquireTargetImage(nsIDOMSVGAnimatedString* aResult,
PRUint8** aTargetData,
gfxImageSurface** aSurface = 0);
const nsRect& GetRect() {
const nsRect& GetRect() const {
return mRect;
}
/*
* Returns total length of data buffer in bytes
*/
PRUint32 GetDataLength() {
PRUint32 GetDataLength() const {
return mStride * mHeight;
}
/*
* Returns the total number of bytes per row of image data
*/
PRInt32 GetDataStride() {
PRInt32 GetDataStride() const {
return mStride;
}
PRInt32 GetWidth() const {
return mWidth;
}
PRInt32 GetHeight() const {
return mHeight;
}
/*
* Copy current sourceImage to targetImage
*/
@ -3596,6 +3606,590 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance)
return NS_OK;
}
//---------------------Convolve Matrix------------------------
typedef nsSVGFE nsSVGFEConvolveMatrixElementBase;
class nsSVGFEConvolveMatrixElement : public nsSVGFEConvolveMatrixElementBase,
public nsIDOMSVGFEConvolveMatrixElement,
public nsISVGFilter
{
protected:
friend nsresult NS_NewSVGFEConvolveMatrixElement(nsIContent **aResult,
nsINodeInfo *aNodeInfo);
nsSVGFEConvolveMatrixElement(nsINodeInfo* aNodeInfo);
nsresult Init();
public:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
// FE Base
NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEConvolveMatrixElementBase::)
// nsISVGFilter
NS_IMETHOD Filter(nsSVGFilterInstance *instance);
NS_IMETHOD GetRequirements(PRUint32 *aRequirements);
// Color Matrix
NS_DECL_NSIDOMSVGFECONVOLVEMATRIXELEMENT
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEConvolveMatrixElementBase::)
NS_FORWARD_NSIDOMNODE(nsSVGFEConvolveMatrixElementBase::)
NS_FORWARD_NSIDOMELEMENT(nsSVGFEConvolveMatrixElementBase::)
virtual PRBool ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
protected:
virtual NumberAttributesInfo GetNumberInfo();
enum { DIVISOR, BIAS, KERNEL_UNIT_LENGTH_X, KERNEL_UNIT_LENGTH_Y };
nsSVGNumber2 mNumberAttributes[4];
static NumberInfo sNumberInfo[4];
nsCOMPtr<nsIDOMSVGAnimatedInteger> mOrderX;
nsCOMPtr<nsIDOMSVGAnimatedInteger> mOrderY;
nsCOMPtr<nsIDOMSVGAnimatedInteger> mTargetX;
nsCOMPtr<nsIDOMSVGAnimatedInteger> mTargetY;
nsCOMPtr<nsIDOMSVGAnimatedNumberList> mKernelMatrix;
nsCOMPtr<nsIDOMSVGAnimatedEnumeration> mEdgeMode;
nsCOMPtr<nsIDOMSVGAnimatedBoolean> mPreserveAlpha;
nsCOMPtr<nsIDOMSVGAnimatedString> mIn1;
};
nsSVGElement::NumberInfo nsSVGFEConvolveMatrixElement::sNumberInfo[4] =
{
{ &nsGkAtoms::divisor, 1 },
{ &nsGkAtoms::bias, 0 },
{ &nsGkAtoms::kernelUnitLength, 0 },
{ &nsGkAtoms::kernelUnitLength, 0 }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(FEConvolveMatrix)
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_ADDREF_INHERITED(nsSVGFEConvolveMatrixElement,nsSVGFEConvolveMatrixElementBase)
NS_IMPL_RELEASE_INHERITED(nsSVGFEConvolveMatrixElement,nsSVGFEConvolveMatrixElementBase)
NS_INTERFACE_MAP_BEGIN(nsSVGFEConvolveMatrixElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGFEConvolveMatrixElement)
NS_INTERFACE_MAP_ENTRY(nsISVGFilter)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGFEConvolveMatrixElement)
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEConvolveMatrixElementBase)
//----------------------------------------------------------------------
// Implementation
nsSVGFEConvolveMatrixElement::nsSVGFEConvolveMatrixElement(nsINodeInfo *aNodeInfo)
: nsSVGFEConvolveMatrixElementBase(aNodeInfo)
{
}
nsresult
nsSVGFEConvolveMatrixElement::Init()
{
nsresult rv = nsSVGFEConvolveMatrixElementBase::Init();
NS_ENSURE_SUCCESS(rv,rv);
static struct nsSVGEnumMapping gEdgeModes[] = {
{&nsGkAtoms::duplicate, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE},
{&nsGkAtoms::wrap, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_WRAP},
{&nsGkAtoms::none, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_NONE},
{nsnull, 0}
};
// Create mapped properties:
// DOM property: edgeMode, #IMPLIED attrib: edgeMode
{
nsCOMPtr<nsISVGEnum> edgeMode;
rv = NS_NewSVGEnum(getter_AddRefs(edgeMode),
nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE,
gEdgeModes);
NS_ENSURE_SUCCESS(rv,rv);
rv = NS_NewSVGAnimatedEnumeration(getter_AddRefs(mEdgeMode), edgeMode);
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::edgeMode, mEdgeMode);
NS_ENSURE_SUCCESS(rv,rv);
}
// DOM property: kernelMarix, #IMPLIED attrib: kernelMatrix
{
nsCOMPtr<nsIDOMSVGNumberList> values;
rv = NS_NewSVGNumberList(getter_AddRefs(values));
NS_ENSURE_SUCCESS(rv,rv);
rv = NS_NewSVGAnimatedNumberList(getter_AddRefs(mKernelMatrix), values);
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::kernelMatrix, mKernelMatrix);
NS_ENSURE_SUCCESS(rv,rv);
}
{
rv = NS_NewSVGAnimatedInteger(getter_AddRefs(mOrderX), 0);
NS_ENSURE_SUCCESS(rv,rv);
rv = NS_NewSVGAnimatedInteger(getter_AddRefs(mOrderY), 0);
NS_ENSURE_SUCCESS(rv,rv);
}
// DOM property: targetX , #IMPLIED attrib: targetX
{
rv = NS_NewSVGAnimatedInteger(getter_AddRefs(mTargetX), 0);
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::targetX, mTargetX);
NS_ENSURE_SUCCESS(rv,rv);
}
// DOM property: targetY , #IMPLIED attrib: targetY
{
rv = NS_NewSVGAnimatedInteger(getter_AddRefs(mTargetY), 0);
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::targetY, mTargetY);
NS_ENSURE_SUCCESS(rv,rv);
}
// DOM property: targetY , #IMPLIED attrib: targetY
{
rv = NS_NewSVGAnimatedBoolean(getter_AddRefs(mPreserveAlpha), PR_FALSE);
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::preserveAlpha, mPreserveAlpha);
NS_ENSURE_SUCCESS(rv,rv);
}
// DOM property: in1 , #IMPLIED attrib: in
{
rv = NS_NewSVGAnimatedString(getter_AddRefs(mIn1));
NS_ENSURE_SUCCESS(rv,rv);
rv = AddMappedSVGValue(nsGkAtoms::in, mIn1);
NS_ENSURE_SUCCESS(rv,rv);
}
return rv;
}
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEConvolveMatrixElement)
//----------------------------------------------------------------------
// nsSVGFEConvolveMatrixElement methods
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
{
*aIn = mIn1;
NS_IF_ADDREF(*aIn);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderX(nsIDOMSVGAnimatedInteger * *aOrderX)
{
*aOrderX = mOrderX;
NS_IF_ADDREF(*aOrderX);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderY(nsIDOMSVGAnimatedInteger * *aOrderY)
{
*aOrderY = mOrderY;
NS_IF_ADDREF(*aOrderY);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetKernelMatrix(nsIDOMSVGAnimatedNumberList * *aKernelMatrix)
{
*aKernelMatrix = mKernelMatrix;
NS_IF_ADDREF(*aKernelMatrix);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetTargetX(nsIDOMSVGAnimatedInteger * *aTargetX)
{
*aTargetX = mTargetX;
NS_IF_ADDREF(*aTargetX);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetTargetY(nsIDOMSVGAnimatedInteger * *aTargetY)
{
*aTargetY = mTargetY;
NS_IF_ADDREF(*aTargetY);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetEdgeMode(nsIDOMSVGAnimatedEnumeration * *aEdgeMode)
{
*aEdgeMode = mEdgeMode;
NS_IF_ADDREF(*aEdgeMode);
return NS_OK;
}
NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetPreserveAlpha(nsIDOMSVGAnimatedBoolean * *aPreserveAlpha)
{
*aPreserveAlpha = mPreserveAlpha;
NS_IF_ADDREF(*aPreserveAlpha);
return NS_OK;
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetDivisor(nsIDOMSVGAnimatedNumber **aDivisor)
{
return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(aDivisor, this);
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetBias(nsIDOMSVGAnimatedNumber **aBias)
{
return mNumberAttributes[BIAS].ToDOMAnimatedNumber(aBias, this);
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetKernelUnitLengthX(nsIDOMSVGAnimatedNumber **aKernelX)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_X].ToDOMAnimatedNumber(aKernelX,
this);
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetKernelUnitLengthY(nsIDOMSVGAnimatedNumber **aKernelY)
{
return mNumberAttributes[KERNEL_UNIT_LENGTH_Y].ToDOMAnimatedNumber(aKernelY,
this);
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::GetRequirements(PRUint32 *aRequirements)
{
*aRequirements = CheckStandardNames(mIn1);
return NS_OK;
}
PRBool
nsSVGFEConvolveMatrixElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aName == nsGkAtoms::order && aNameSpaceID == kNameSpaceID_None) {
PRInt32 x = 0, y = 0;
char *rest;
PRBool parseError = PR_FALSE;
NS_ConvertUTF16toUTF8 value(aValue);
value.CompressWhitespace(PR_FALSE, PR_TRUE);
const char *str = value.get();
x = strtol(str, &rest, 10);
if (str == rest) {
//first value was illformed
parseError = PR_TRUE;
} else {
if (*rest == '\0') {
//second value was not supplied
y = x;
} else {
y = strtol(rest, &rest, 10);
if (*rest != '\0') {
//second value was illformed or there was trailing content
parseError = PR_TRUE;
}
}
}
mOrderX->SetBaseVal(x);
mOrderY->SetBaseVal(y);
if (parseError) {
ReportAttributeParseFailure(GetOwnerDoc(), aName, aValue);
return PR_FALSE;
}
aResult.SetTo(aValue);
return PR_TRUE;
}
if (aName == nsGkAtoms::kernelUnitLength && aNameSpaceID == kNameSpaceID_None) {
return ScanDualValueAttribute(aValue, nsGkAtoms::kernelUnitLength,
&mNumberAttributes[KERNEL_UNIT_LENGTH_X],
&mNumberAttributes[KERNEL_UNIT_LENGTH_Y],
&sNumberInfo[KERNEL_UNIT_LENGTH_X],
&sNumberInfo[KERNEL_UNIT_LENGTH_Y],
aResult);
}
return nsSVGFEConvolveMatrixElementBase::ParseAttribute(aNameSpaceID, aName,
aValue, aResult);
}
#define BOUND(val, min, max) \
PR_MIN(PR_MAX(val, min), max)
#define WRAP(val, min, max) \
(val < 0 ? (val + val % max) : val % max)
static void
ConvolvePixel(const PRUint8 *aSourceData,
PRUint8 *aTargetData,
PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aStride,
PRInt32 aX, PRInt32 aY,
PRUint16 aEdgeMode,
const float *aKernel,
float aDivisor, float aBias,
PRBool aPreserveAlpha,
PRInt32 aOrderX, PRInt32 aOrderY,
PRInt32 aTargetX, PRInt32 aTargetY)
{
float sum[4] = {0, 0, 0, 0};
aBias *= 255;
PRInt32 offsets[4] = {GFX_ARGB32_OFFSET_R,
GFX_ARGB32_OFFSET_G,
GFX_ARGB32_OFFSET_B,
GFX_ARGB32_OFFSET_A } ;
PRInt32 channels = aPreserveAlpha ? 3 : 4;
for (PRInt32 y = 0; y < aOrderY; y++) {
PRInt32 sampleY = aY + y - aTargetY;
PRBool overscanY = sampleY < 0 || sampleY >= aHeight;
for (PRInt32 x = 0; x < aOrderX; x++) {
PRInt32 sampleX = aX + x - aTargetX;
PRBool overscanX = sampleX < 0 || sampleX >= aWidth;
for (PRInt32 i = 0; i < channels; i++) {
if (overscanY || overscanX) {
switch (aEdgeMode) {
case nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE:
sum[i] +=
aSourceData[BOUND(sampleY, 0, aHeight - 1) * aStride +
BOUND(sampleX, 0, aWidth - 1) * 4 + offsets[i]] *
aKernel[aOrderX * y + x];
break;
case nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_WRAP:
sum[i] +=
aSourceData[WRAP(sampleY, 0, aHeight) * aStride +
WRAP(sampleX, 0, aWidth) * 4 + offsets[i]] *
aKernel[aOrderX * y + x];
break;
default:
break;
}
} else {
sum[i] +=
aSourceData[sampleY * aStride + 4 * sampleX + offsets[i]] *
aKernel[aOrderX * y + x];
}
}
}
}
for (PRInt32 i = 0; i < channels; i++) {
aTargetData[aY * aStride + 4 * aX + offsets[i]] =
BOUND(NS_STATIC_CAST(PRInt32, sum[i] / aDivisor + aBias * 255), 0, 255);
}
if (aPreserveAlpha) {
aTargetData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A] =
aSourceData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A];
}
}
NS_IMETHODIMP
nsSVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance *instance)
{
PRBool preserveAlpha;
mPreserveAlpha->GetAnimVal(&preserveAlpha);
nsCOMPtr<nsIDOMSVGNumberList> list;
mKernelMatrix->GetAnimVal(getter_AddRefs(list));
PRUint32 num = 0;
if (list) {
list->GetNumberOfItems(&num);
}
PRInt32 orderX, orderY;
mOrderX->GetAnimVal(&orderX);
mOrderY->GetAnimVal(&orderY);
if (orderX <= 0 || orderY <= 0 ||
NS_STATIC_CAST(PRUint32, orderX * orderY) != num) {
return NS_ERROR_FAILURE;
}
PRInt32 targetX, targetY;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::targetX)) {
mTargetX->GetAnimVal(&targetX);
if (targetX < 0 || targetX >= orderX)
return NS_ERROR_FAILURE;
} else {
targetX = orderX / 2;
}
if (HasAttr(kNameSpaceID_None, nsGkAtoms::targetY)) {
mTargetY->GetAnimVal(&targetY);
if (targetY < 0 || targetY >= orderY)
return NS_ERROR_FAILURE;
} else {
targetY = orderY / 2;
}
if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
return NS_ERROR_FAILURE;
nsAutoPtr<float> kernel(new float[orderX * orderY]);
if (!kernel)
return NS_ERROR_FAILURE;
for (PRUint32 i = 0; i < num; i++) {
nsCOMPtr<nsIDOMSVGNumber> number;
list->GetItem(i, getter_AddRefs(number));
// svg specification flips the kernel from what one might expect
number->GetValue(&kernel[num - 1 - i]);
}
float divisor;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::divisor)) {
divisor = mNumberAttributes[DIVISOR].GetAnimValue();
if (divisor == 0)
return NS_ERROR_FAILURE;
} else {
divisor = kernel[0];
for (PRUint32 i = 1; i < num; i++)
divisor += kernel[i];
if (divisor == 0)
divisor = 1;
}
nsSVGFilterResource
fr(instance, GetColorModel(preserveAlpha
? nsSVGFilterInstance::ColorModel::UNPREMULTIPLIED
: nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
nsresult rv;
PRUint8 *sourceData, *targetData;
nsRefPtr<gfxImageSurface> sourceSurface, targetSurface;
rv = fr.AcquireSourceImage(mIn1, this, &sourceData,
getter_AddRefs(sourceSurface));
NS_ENSURE_SUCCESS(rv, rv);
rv = fr.AcquireTargetImage(mResult, &targetData,
getter_AddRefs(targetSurface));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<gfxImageSurface> scaledSource, scaledTarget;
PRBool rescaling = PR_FALSE;
float kernelX, kernelY;
gfxIntSize scaledSize;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::kernelUnitLength)) {
rescaling = PR_TRUE;
nsSVGLength2 val;
val.Init(nsSVGUtils::X, 0xff,
mNumberAttributes[KERNEL_UNIT_LENGTH_X].GetAnimValue(),
nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
kernelX = instance->GetPrimitiveLength(&val);
val.Init(nsSVGUtils::Y, 0xff,
mNumberAttributes[KERNEL_UNIT_LENGTH_Y].GetAnimValue(),
nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
kernelY = instance->GetPrimitiveLength(&val);
#ifdef DEBUG_tor
fprintf(stderr, "convolve kernelX/Y %f %f\n", kernelX, kernelY);
#endif
if (kernelX <= 0 || kernelY <= 0)
return NS_ERROR_FAILURE;
PRBool overflow = PR_FALSE;
scaledSize =
nsSVGUtils::ConvertToSurfaceSize(gfxSize(fr.GetWidth() / kernelX,
fr.GetHeight() / kernelY),
&overflow);
// If the requested size based on the kernel unit is too big, we
// need to bail because the effect is pixel size dependent. Also
// need to check if we ended up with a negative size (arithmetic
// overflow) or zero size (large kernel unit)
if (overflow || scaledSize.width <= 0 || scaledSize.height <= 0)
return NS_ERROR_FAILURE;
#ifdef DEBUG_tor
fprintf(stderr, "scaled size %d %d\n", scaledSize.width, scaledSize.height);
#endif
scaledSource = new gfxImageSurface(scaledSize,
gfxASurface::ImageFormatARGB32);
scaledTarget = new gfxImageSurface(scaledSize,
gfxASurface::ImageFormatARGB32);
if (!scaledSource || !scaledSource->Data() ||
!scaledTarget || !scaledTarget->Data())
return NS_ERROR_FAILURE;
gfxContext ctx(scaledSource);
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
ctx.Scale(double(scaledSize.width) / fr.GetWidth(),
double(scaledSize.height) / fr.GetHeight());
ctx.SetSource(sourceSurface);
ctx.Paint();
}
nsRect rect = fr.GetRect();
#ifdef DEBUG_tor
fprintf(stderr, "FILTER CONVOLVE MATRIX rect: %d,%d %dx%d\n",
rect.x, rect.y, rect.width, rect.height);
#endif
PRUint16 edgeMode;
mEdgeMode->GetAnimVal(&edgeMode);
float bias = 0;
if (HasAttr(kNameSpaceID_None, nsGkAtoms::bias)) {
bias = mNumberAttributes[BIAS].GetAnimValue();
}
PRInt32 stride, width, height;
if (rescaling) {
rect.x = rect.x * scaledSize.width / fr.GetWidth();
rect.y = rect.y * scaledSize.height / fr.GetHeight();
rect.width = rect.width * scaledSize.width / fr.GetWidth();
rect.height = rect.height * scaledSize.height / fr.GetHeight();
sourceData = scaledSource->Data();
targetData = scaledTarget->Data();
stride = scaledSource->Stride();
width = scaledSize.width;
height = scaledSize.height;
} else {
stride = fr.GetDataStride();
width = fr.GetWidth();
height = fr.GetHeight();
}
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
ConvolvePixel(sourceData, targetData,
width, height, stride,
x, y,
edgeMode, kernel, divisor, bias, preserveAlpha,
orderX, orderY, targetX, targetY);
}
}
if (rescaling) {
gfxContext ctx(targetSurface);
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
ctx.Scale(double(fr.GetWidth()) / scaledSize.width,
double(fr.GetHeight()) /scaledSize.height);
ctx.SetSource(scaledTarget);
ctx.Paint();
}
return NS_OK;
}
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::NumberAttributesInfo
nsSVGFEConvolveMatrixElement::GetNumberInfo()
{
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
NS_ARRAY_LENGTH(sNumberInfo));
}
//---------------------UnimplementedMOZ------------------------
typedef nsSVGFE nsSVGFEUnimplementedMOZElementBase;

Просмотреть файл

@ -53,6 +53,7 @@ XPIDLSRCS = \
nsIDOMSVGAElement.idl \
nsIDOMSVGAngle.idl \
nsIDOMSVGAnimatedAngle.idl \
nsIDOMSVGAnimatedBoolean.idl \
nsIDOMSVGAnimatedEnum.idl \
nsIDOMSVGAnimatedInteger.idl \
nsIDOMSVGAnimatedLength.idl \

Просмотреть файл

@ -0,0 +1,56 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ----- BEGIN LICENSE BLOCK -----
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#include "domstubs.idl"
/**
* The nsIDOMSVGAnimatedBoolean interface is the interface to an SVG
* animated boolean.
*
* For more information on this interface please see
* http://www.w3.org/TR/SVG11/types.html
*
*/
[scriptable, uuid(7e325385-cc82-4763-bd14-e2c92edd5462)]
interface nsIDOMSVGAnimatedBoolean : nsISupports
{
attribute boolean baseVal;
// raises DOMException on setting
readonly attribute boolean animVal;
};

Просмотреть файл

@ -43,6 +43,7 @@ interface nsIDOMSVGAnimatedNumber;
interface nsIDOMSVGAnimatedEnumeration;
interface nsIDOMSVGAnimatedNumberList;
interface nsIDOMSVGAnimatedInteger;
interface nsIDOMSVGAnimatedBoolean;
[scriptable, uuid(ab68567a-b830-4c46-9f2f-a28513a9e980)]
interface nsIDOMSVGFilterPrimitiveStandardAttributes : nsIDOMSVGElement
@ -225,6 +226,29 @@ interface nsIDOMSVGFEMorphologyElement : nsIDOMSVGFilterPrimitiveStandardAttribu
void setRadius ( in float rx, in float ry );
};
[scriptable, uuid(42109b58-a8c1-4078-b44c-ec1d5d6b9574)]
interface nsIDOMSVGFEConvolveMatrixElement : nsIDOMSVGFilterPrimitiveStandardAttributes
{
// Edge Mode Values
const unsigned short SVG_EDGEMODE_UNKNOWN = 0;
const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
const unsigned short SVG_EDGEMODE_WRAP = 2;
const unsigned short SVG_EDGEMODE_NONE = 3;
readonly attribute nsIDOMSVGAnimatedString in1;
readonly attribute nsIDOMSVGAnimatedInteger orderX;
readonly attribute nsIDOMSVGAnimatedInteger orderY;
readonly attribute nsIDOMSVGAnimatedNumberList kernelMatrix;
readonly attribute nsIDOMSVGAnimatedNumber divisor;
readonly attribute nsIDOMSVGAnimatedNumber bias;
readonly attribute nsIDOMSVGAnimatedInteger targetX;
readonly attribute nsIDOMSVGAnimatedInteger targetY;
readonly attribute nsIDOMSVGAnimatedEnumeration edgeMode;
readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthX;
readonly attribute nsIDOMSVGAnimatedNumber kernelUnitLengthY;
readonly attribute nsIDOMSVGAnimatedBoolean preserveAlpha;
};
[scriptable, uuid(8698c635-26c7-468b-905e-494e8825d56b)]
interface nsIDOMSVGFEUnimplementedMOZElement : nsIDOMSVGFilterPrimitiveStandardAttributes
{

Просмотреть файл

@ -250,6 +250,7 @@ enum nsDOMClassInfoID {
eDOMClassInfo_SVGFEColorMatrixElement_id,
eDOMClassInfo_SVGFEComponentTransferElement_id,
eDOMClassInfo_SVGFECompositeElement_id,
eDOMClassInfo_SVGFEConvolveMatrixElement_id,
eDOMClassInfo_SVGFEFloodElement_id,
eDOMClassInfo_SVGFEFuncAElement_id,
eDOMClassInfo_SVGFEFuncBElement_id,
@ -291,6 +292,7 @@ enum nsDOMClassInfoID {
// other SVG classes
eDOMClassInfo_SVGAngle_id,
eDOMClassInfo_SVGAnimatedAngle_id,
eDOMClassInfo_SVGAnimatedBoolean_id,
eDOMClassInfo_SVGAnimatedEnumeration_id,
eDOMClassInfo_SVGAnimatedInteger_id,
eDOMClassInfo_SVGAnimatedLength_id,

Просмотреть файл

@ -345,6 +345,7 @@
#include "nsIDOMSVGAElement.h"
#include "nsIDOMSVGAngle.h"
#include "nsIDOMSVGAnimatedAngle.h"
#include "nsIDOMSVGAnimatedBoolean.h"
#include "nsIDOMSVGAnimatedEnum.h"
#include "nsIDOMSVGAnimatedInteger.h"
#include "nsIDOMSVGAnimatedLength.h"
@ -914,6 +915,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGFECompositeElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGFEConvolveMatrixElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGFEFloodElement, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGFEFuncAElement, nsElementSH,
@ -994,6 +997,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedAngle, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedBoolean, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedEnumeration, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SVGAnimatedInteger, nsDOMGenericSH,
@ -2628,6 +2633,13 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGFEConvolveMatrixElement, nsIDOMSVGFEConvolveMatrixElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEConvolveMatrixElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGFEFloodElement, nsIDOMSVGFEFloodElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEFloodElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
@ -2874,6 +2886,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedAngle)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedBoolean, nsIDOMSVGAnimatedBoolean)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedBoolean)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SVGAnimatedEnumeration, nsIDOMSVGAnimatedEnumeration)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGAnimatedEnumeration)
DOM_CLASSINFO_MAP_END