зеркало из https://github.com/mozilla/pjs.git
Bug 355249 - implement feMorphology.
Patch by amenzie@us.ibm.com, r=tor, sr=roc
This commit is contained in:
Родитель
89b633441a
Коммит
4079e1a82f
|
@ -895,6 +895,7 @@ GK_ATOM(defs, "defs")
|
|||
GK_ATOM(definition_src, "definition-src")
|
||||
GK_ATOM(deg, "deg")
|
||||
GK_ATOM(desc, "desc")
|
||||
GK_ATOM(dilate, "dilate")
|
||||
GK_ATOM(direction, "direction")
|
||||
GK_ATOM(disable, "disable")
|
||||
GK_ATOM(discrete, "discrete")
|
||||
|
@ -902,6 +903,7 @@ GK_ATOM(dominant_baseline, "dominant-baseline")
|
|||
GK_ATOM(dx, "dx")
|
||||
GK_ATOM(dy, "dy")
|
||||
GK_ATOM(ellipse, "ellipse")
|
||||
GK_ATOM(erode, "erode")
|
||||
GK_ATOM(ex, "ex")
|
||||
GK_ATOM(exact, "exact")
|
||||
GK_ATOM(exponent, "exponent")
|
||||
|
@ -997,6 +999,7 @@ GK_ATOM(onSVGUnload, "onSVGUnload")
|
|||
GK_ATOM(onSVGZoom, "onSVGZoom")
|
||||
GK_ATOM(onzoom, "onzoom")
|
||||
GK_ATOM(opacity, "opacity")
|
||||
GK_ATOM(_operator, "operator")
|
||||
GK_ATOM(pad, "pad")
|
||||
GK_ATOM(path, "path")
|
||||
GK_ATOM(pathLength, "pathLength")
|
||||
|
@ -1015,6 +1018,7 @@ GK_ATOM(px, "px")
|
|||
GK_ATOM(r, "r")
|
||||
GK_ATOM(rad, "rad")
|
||||
GK_ATOM(radialGradient, "radialGradient")
|
||||
GK_ATOM(radius, "radius")
|
||||
GK_ATOM(reflect, "reflect")
|
||||
GK_ATOM(refX, "refX")
|
||||
GK_ATOM(refY, "refY")
|
||||
|
|
|
@ -191,16 +191,13 @@ protected:
|
|||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual NumberAttributesInfo GetNumberInfo();
|
||||
|
||||
static nsresult ReportAttributeParseFailure(nsIDocument* aDocument,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue);
|
||||
nsCOMPtr<nsICSSStyleRule> mContentStyleRule;
|
||||
nsAttrAndChildArray mMappedAttributes;
|
||||
|
||||
PRPackedBool mSuppressNotification;
|
||||
|
||||
private:
|
||||
static nsresult
|
||||
ReportAttributeParseFailure(nsIDocument* aDocument,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -121,6 +121,8 @@ NS_NewSVGFEMergeElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
|||
nsresult
|
||||
NS_NewSVGFEMergeNodeElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGFEMorphologyElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGFEOffsetElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
nsresult
|
||||
NS_NewSVGFEUnimplementedMOZElement(nsIContent **aResult, nsINodeInfo *aNodeInfo);
|
||||
|
@ -218,6 +220,8 @@ NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
|
|||
return NS_NewSVGFEMergeElement(aResult, aNodeInfo);
|
||||
if (name == nsSVGAtoms::feMergeNode)
|
||||
return NS_NewSVGFEMergeNodeElement(aResult, aNodeInfo);
|
||||
if (name == nsSVGAtoms::feMorphology)
|
||||
return NS_NewSVGFEMorphologyElement(aResult, aNodeInfo);
|
||||
if (name == nsSVGAtoms::feOffset)
|
||||
return NS_NewSVGFEOffsetElement(aResult, aNodeInfo);
|
||||
if (name == nsSVGAtoms::feBlend ||
|
||||
|
@ -228,7 +232,6 @@ NS_NewSVGElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
|
|||
name == nsSVGAtoms::feDisplacementMap ||
|
||||
name == nsSVGAtoms::feFlood ||
|
||||
name == nsSVGAtoms::feImage ||
|
||||
name == nsSVGAtoms::feMorphology ||
|
||||
name == nsSVGAtoms::feSpecularLighting ||
|
||||
name == nsSVGAtoms::feTile ||
|
||||
name == nsSVGAtoms::feTurbulence)
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsISVGValueUtils.h"
|
||||
#include "nsSVGFilters.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "prdtoa.h"
|
||||
|
||||
nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
|
||||
{
|
||||
|
@ -119,6 +120,47 @@ nsSVGFE::DidModifySVGObservable (nsISVGValue* observable,
|
|||
return nsSVGFEBase::DidModifySVGObservable(observable, aModType);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGFE::ScanDualValueAttribute(const nsAString& aValue, nsIAtom* aAttribute,
|
||||
nsSVGNumber2* aNum1, nsSVGNumber2* aNum2,
|
||||
NumberInfo* aInfo1, NumberInfo* aInfo2,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
float x = 0.0f, y = 0.0f;
|
||||
char *rest;
|
||||
PRBool parseError = PR_FALSE;
|
||||
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
value.CompressWhitespace(PR_FALSE, PR_TRUE);
|
||||
const char *str = value.get();
|
||||
x = NS_STATIC_CAST(float, PR_strtod(str, &rest));
|
||||
if (str == rest) {
|
||||
//first value was illformed
|
||||
parseError = PR_TRUE;
|
||||
} else {
|
||||
if (*rest == '\0') {
|
||||
//second value was not supplied
|
||||
y = x;
|
||||
} else {
|
||||
y = NS_STATIC_CAST(float, PR_strtod(rest, &rest));
|
||||
if (*rest != '\0') {
|
||||
//second value was illformed or there was trailing content
|
||||
parseError = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parseError) {
|
||||
ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue);
|
||||
x = aInfo1->mDefaultValue;
|
||||
y = aInfo2->mDefaultValue;
|
||||
return PR_FALSE;
|
||||
}
|
||||
aNum1->SetBaseValue(x, this, PR_FALSE);
|
||||
aNum2->SetBaseValue(y, this, PR_FALSE);
|
||||
aResult.SetTo(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGFilterPrimitiveStandardAttributes methods
|
||||
|
@ -409,9 +451,9 @@ public:
|
|||
NS_FORWARD_NSIDOMNODE(nsSVGFEGaussianBlurElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGFEGaussianBlurElementBase::)
|
||||
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual PRBool ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
|
@ -511,27 +553,21 @@ nsSVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviat
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFEGaussianBlurElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
PRBool
|
||||
nsSVGFEGaussianBlurElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
nsresult rv = nsSVGFEGaussianBlurElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
|
||||
if (aName == nsSVGAtoms::stdDeviation && aNameSpaceID == kNameSpaceID_None) {
|
||||
float stdX = 0.0f, stdY = 0.0f;
|
||||
char *str;
|
||||
str = ToNewCString(aValue);
|
||||
int num = sscanf(str, "%f %f\n", &stdX, &stdY);
|
||||
if (num == 1)
|
||||
stdY = stdX;
|
||||
mNumberAttributes[STD_DEV_X].SetBaseValue(stdX, this, PR_FALSE);
|
||||
mNumberAttributes[STD_DEV_Y].SetBaseValue(stdY, this, PR_FALSE);
|
||||
nsMemory::Free(str);
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::stdDeviation,
|
||||
&mNumberAttributes[STD_DEV_X],
|
||||
&mNumberAttributes[STD_DEV_Y],
|
||||
&sNumberInfo[STD_DEV_X],
|
||||
&sNumberInfo[STD_DEV_Y],
|
||||
aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return nsSVGFEGaussianBlurElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1899,6 +1935,301 @@ nsSVGFEOffsetElement::GetNumberInfo()
|
|||
NS_ARRAY_LENGTH(sNumberInfo));
|
||||
}
|
||||
|
||||
//---------------------Morphology------------------------
|
||||
|
||||
typedef nsSVGFE nsSVGFEMorphologyElementBase;
|
||||
|
||||
class nsSVGFEMorphologyElement : public nsSVGFEMorphologyElementBase,
|
||||
public nsIDOMSVGFEMorphologyElement,
|
||||
public nsISVGFilter
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGFEMorphologyElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGFEMorphologyElement(nsINodeInfo* aNodeInfo);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// FE Base
|
||||
NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEMorphologyElementBase::)
|
||||
|
||||
// nsISVGFilter
|
||||
NS_IMETHOD Filter(nsSVGFilterInstance *instance);
|
||||
NS_IMETHOD GetRequirements(PRUint32 *aRequirements);
|
||||
|
||||
// Morphology
|
||||
NS_DECL_NSIDOMSVGFEMORPHOLOGYELEMENT
|
||||
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMorphologyElementBase::)
|
||||
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGFEMorphologyElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGFEMorphologyElementBase::)
|
||||
|
||||
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 { RADIUS_X, RADIUS_Y };
|
||||
nsSVGNumber2 mNumberAttributes[2];
|
||||
static NumberInfo sNumberInfo[2];
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mIn1;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedEnumeration> mOperator;
|
||||
};
|
||||
|
||||
nsSVGElement::NumberInfo nsSVGFEMorphologyElement::sNumberInfo[2] =
|
||||
{
|
||||
{ &nsGkAtoms::radius, 0 },
|
||||
{ &nsGkAtoms::radius, 0 }
|
||||
};
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(FEMorphology)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsSVGFEMorphologyElement,nsSVGFEMorphologyElementBase)
|
||||
NS_IMPL_RELEASE_INHERITED(nsSVGFEMorphologyElement,nsSVGFEMorphologyElementBase)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGFEMorphologyElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGFEMorphologyElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGFilter)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGFEMorphologyElement)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEMorphologyElementBase)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsSVGFEMorphologyElement::nsSVGFEMorphologyElement(nsINodeInfo *aNodeInfo)
|
||||
: nsSVGFEMorphologyElementBase(aNodeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFEMorphologyElement::Init()
|
||||
{
|
||||
nsresult rv = nsSVGFEMorphologyElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
static struct nsSVGEnumMapping gOperatorTypes[] = {
|
||||
{&nsSVGAtoms::erode, nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE},
|
||||
{&nsSVGAtoms::dilate, nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE},
|
||||
{nsnull, 0}
|
||||
};
|
||||
|
||||
// Create mapped properties:
|
||||
// DOM property: operator, #IMPLIED attrib: operator
|
||||
{
|
||||
nsCOMPtr<nsISVGEnum> operators;
|
||||
rv = NS_NewSVGEnum(getter_AddRefs(operators),
|
||||
nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE,
|
||||
gOperatorTypes);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedEnumeration(getter_AddRefs(mOperator), operators);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::_operator, mOperator);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: in1 , #IMPLIED attrib: in
|
||||
{
|
||||
rv = NS_NewSVGAnimatedString(getter_AddRefs(mIn1));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::in, mIn1);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMNode methods
|
||||
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEMorphologyElement)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGFEMorphologyElement methods
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedString in1; */
|
||||
NS_IMETHODIMP nsSVGFEMorphologyElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
|
||||
{
|
||||
*aIn = mIn1;
|
||||
NS_IF_ADDREF(*aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedEnumeration operator; */
|
||||
NS_IMETHODIMP nsSVGFEMorphologyElement::GetOperator(nsIDOMSVGAnimatedEnumeration * *aOperator)
|
||||
{
|
||||
*aOperator = mOperator;
|
||||
NS_IF_ADDREF(*aOperator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedNumber radiusX; */
|
||||
NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusX(nsIDOMSVGAnimatedNumber * *aX)
|
||||
{
|
||||
return mNumberAttributes[RADIUS_X].ToDOMAnimatedNumber(aX, this);
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedNumber radiusY; */
|
||||
NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusY(nsIDOMSVGAnimatedNumber * *aY)
|
||||
{
|
||||
return mNumberAttributes[RADIUS_Y].ToDOMAnimatedNumber(aY, this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGFEMorphologyElement::SetRadius(float rx, float ry)
|
||||
{
|
||||
mNumberAttributes[RADIUS_X].SetBaseValue(rx, this, PR_TRUE);
|
||||
mNumberAttributes[RADIUS_Y].SetBaseValue(ry, this, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGFEMorphologyElement::ParseAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aName == nsSVGAtoms::radius && aNameSpaceID == kNameSpaceID_None) {
|
||||
return ScanDualValueAttribute(aValue, nsGkAtoms::radius,
|
||||
&mNumberAttributes[RADIUS_X],
|
||||
&mNumberAttributes[RADIUS_Y],
|
||||
&sNumberInfo[RADIUS_X],
|
||||
&sNumberInfo[RADIUS_Y],
|
||||
aResult);
|
||||
}
|
||||
return nsSVGFEMorphologyElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
aValue, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGFEMorphologyElement::GetRequirements(PRUint32 *aRequirements)
|
||||
{
|
||||
*aRequirements = CheckStandardNames(mIn1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
nsSVGElement::NumberAttributesInfo
|
||||
nsSVGFEMorphologyElement::GetNumberInfo()
|
||||
{
|
||||
return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
|
||||
NS_ARRAY_LENGTH(sNumberInfo));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = fr.AcquireTargetImage(mResult, &targetData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRect rect = fr.GetRect();
|
||||
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "FILTER MORPH rect: %d,%d %dx%d\n",
|
||||
rect.x, rect.y, rect.width, rect.height);
|
||||
#endif
|
||||
|
||||
float rx, ry;
|
||||
nsSVGLength2 val;
|
||||
|
||||
GetAnimatedNumberValues(&rx, &ry, nsnull);
|
||||
val.Init(nsSVGUtils::X, 0xff, rx, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
|
||||
rx = instance->GetPrimitiveLength(&val);
|
||||
val.Init(nsSVGUtils::Y, 0xff, ry, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
|
||||
ry = instance->GetPrimitiveLength(&val);
|
||||
|
||||
PRInt32 stride = fr.GetDataStride();
|
||||
PRUint32 xExt[4], yExt[4]; // X, Y indices of RGBA extrema
|
||||
PRUint8 extrema[4]; // RGBA magnitude of extrema
|
||||
PRUint16 op;
|
||||
mOperator->GetAnimVal(&op);
|
||||
|
||||
if (rx == 0 && ry == 0) {
|
||||
memcpy(targetData, sourceData, rect.height * stride);
|
||||
return NS_OK;
|
||||
}
|
||||
/* Scan the kernel for each pixel to determine max/min RGBA values. Note that
|
||||
* as we advance in the x direction, each kernel overlaps the previous kernel.
|
||||
* Thus, we can avoid iterating over the entire kernel by comparing the
|
||||
* leading edge of the new kernel against the extrema found in the previous
|
||||
* kernel. We must still scan the entire kernel if the previous extrema do
|
||||
* not fall within the current kernel or if we are starting a new row.
|
||||
*/
|
||||
for (PRInt32 y = rect.y; y < rect.y + rect.height; y++) {
|
||||
PRUint32 startY = PR_MAX(0, (int)(y - ry));
|
||||
PRUint32 endY = PR_MIN((int)(y + ry), rect.y + rect.height - 1);
|
||||
for (PRInt32 x = rect.x; x < rect.x + rect.width; x++) {
|
||||
PRUint32 startX = PR_MAX(0, (int)(x - rx));
|
||||
PRUint32 endX = PR_MIN((int)(x + rx), rect.x + rect.width - 1);
|
||||
PRUint32 targIndex = y * stride + 4 * x;
|
||||
|
||||
// We need to scan the entire kernel
|
||||
if (x == rect.x || xExt[0] <= startX || xExt[1] <= startX ||
|
||||
xExt[2] <= startX || xExt[3] <= startX) {
|
||||
PRUint32 i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
extrema[i] = sourceData[targIndex + i];
|
||||
}
|
||||
for (PRUint32 y1 = startY; y1 <= endY; y1++) {
|
||||
for (PRUint32 x1 = startX; x1 <= endX; x1++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
PRUint8 pixel = sourceData[y1 * stride + 4 * x1 + i];
|
||||
if ((extrema[i] >= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE) ||
|
||||
(extrema[i] <= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE)) {
|
||||
extrema[i] = pixel;
|
||||
xExt[i] = x1;
|
||||
yExt[i] = y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // We only need to look at the newest column
|
||||
for (PRUint32 y1 = startY; y1 <= endY; y1++) {
|
||||
for (PRUint32 i = 0; i < 4; i++) {
|
||||
PRUint8 pixel = sourceData[y1 * stride + 4 * endX + i];
|
||||
if ((extrema[i] >= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE) ||
|
||||
(extrema[i] <= pixel &&
|
||||
op == nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE)) {
|
||||
extrema[i] = pixel;
|
||||
xExt[i] = endX;
|
||||
yExt[i] = y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetData[targIndex ] = extrema[0];
|
||||
targetData[targIndex+1] = extrema[1];
|
||||
targetData[targIndex+2] = extrema[2];
|
||||
targetData[targIndex+3] = extrema[3];
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------UnimplementedMOZ------------------------
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ protected:
|
|||
nsISVGValue::modificationType aModType);
|
||||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType);
|
||||
PRBool ScanDualValueAttribute(const nsAString& aValue, nsIAtom* aAttribute,
|
||||
nsSVGNumber2* aNum1, nsSVGNumber2* aNum2,
|
||||
NumberInfo* aInfo1, NumberInfo* aInfo2,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
|
|
@ -129,6 +129,21 @@ interface nsIDOMSVGFEOffsetElement : nsIDOMSVGFilterPrimitiveStandardAttributes
|
|||
readonly attribute nsIDOMSVGAnimatedNumber dy;
|
||||
};
|
||||
|
||||
[scriptable, uuid(16154319-FB5F-4473-B360-5065B6096D33)]
|
||||
interface nsIDOMSVGFEMorphologyElement : nsIDOMSVGFilterPrimitiveStandardAttributes
|
||||
{
|
||||
// Operator Types
|
||||
const unsigned short SVG_OPERATOR_UNKNOWN = 0;
|
||||
const unsigned short SVG_OPERATOR_ERODE = 1;
|
||||
const unsigned short SVG_OPERATOR_DILATE = 2;
|
||||
|
||||
readonly attribute nsIDOMSVGAnimatedString in1;
|
||||
readonly attribute nsIDOMSVGAnimatedNumber radiusX;
|
||||
readonly attribute nsIDOMSVGAnimatedNumber radiusY;
|
||||
readonly attribute nsIDOMSVGAnimatedEnumeration operator;
|
||||
|
||||
void setRadius ( in float rx, in float ry );
|
||||
};
|
||||
|
||||
[scriptable, uuid(8698c635-26c7-468b-905e-494e8825d56b)]
|
||||
interface nsIDOMSVGFEUnimplementedMOZElement : nsIDOMSVGFilterPrimitiveStandardAttributes
|
||||
|
|
|
@ -252,6 +252,7 @@ enum nsDOMClassInfoID {
|
|||
eDOMClassInfo_SVGFEGaussianBlurElement_id,
|
||||
eDOMClassInfo_SVGFEMergeElement_id,
|
||||
eDOMClassInfo_SVGFEMergeNodeElement_id,
|
||||
eDOMClassInfo_SVGFEMorphologyElement_id,
|
||||
eDOMClassInfo_SVGFEOffsetElement_id,
|
||||
eDOMClassInfo_SVGFEUnimplementedMOZElement_id,
|
||||
eDOMClassInfo_SVGFilterElement_id,
|
||||
|
|
|
@ -917,6 +917,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGFEMergeNodeElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGFEMorphologyElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGFEOffsetElement, nsElementSH,
|
||||
ELEMENT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(SVGFEUnimplementedMOZElement, nsElementSH,
|
||||
|
@ -2594,6 +2596,13 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(SVGFEMorphologyElement, nsIDOMSVGFEMorphologyElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEMorphologyElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)
|
||||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(SVGFEMergeNodeElement, nsIDOMSVGFEMergeNodeElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEMergeNodeElement)
|
||||
DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
|
||||
|
|
Загрузка…
Ссылка в новой задаче