mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 948265 - Support SourceAlpha keyword in SVG filter chains. r=mstange
This commit is contained in:
parent
4f90ee5e92
commit
3a832415cc
@ -966,6 +966,11 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
||||
return transform;
|
||||
}
|
||||
|
||||
case PrimitiveType::ToAlpha:
|
||||
{
|
||||
return FilterWrappers::ToAlpha(aDT, aSources[0]);
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@ -1001,6 +1006,7 @@ InputAlphaModelForPrimitive(const FilterPrimitiveDescription& aDescr,
|
||||
switch (aDescr.Type()) {
|
||||
case PrimitiveType::Tile:
|
||||
case PrimitiveType::Offset:
|
||||
case PrimitiveType::ToAlpha:
|
||||
return aOriginalAlphaModel;
|
||||
|
||||
case PrimitiveType::ColorMatrix:
|
||||
@ -1196,6 +1202,7 @@ ResultChangeRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
|
||||
|
||||
case PrimitiveType::ColorMatrix:
|
||||
case PrimitiveType::ComponentTransfer:
|
||||
case PrimitiveType::ToAlpha:
|
||||
return aInputChangeRegions[0];
|
||||
|
||||
case PrimitiveType::Morphology:
|
||||
@ -1425,6 +1432,7 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
|
||||
case PrimitiveType::Merge:
|
||||
case PrimitiveType::ColorMatrix:
|
||||
case PrimitiveType::ComponentTransfer:
|
||||
case PrimitiveType::ToAlpha:
|
||||
return aResultNeededRegion;
|
||||
|
||||
case PrimitiveType::Morphology:
|
||||
|
@ -270,6 +270,7 @@ MOZ_BEGIN_ENUM_CLASS(PrimitiveType)
|
||||
DropShadow,
|
||||
DiffuseLighting,
|
||||
SpecularLighting,
|
||||
ToAlpha,
|
||||
Max
|
||||
MOZ_END_ENUM_CLASS(PrimitiveType)
|
||||
|
||||
|
@ -9,5 +9,6 @@ default-preferences pref(layout.css.filters.enabled,true)
|
||||
== intersecting-filter-regions.svg intersecting-filter-regions-ref.svg
|
||||
== long-chain.svg simple-chain-ref.svg
|
||||
== multiple-primitives-per-filter.svg simple-chain-ref.svg
|
||||
== second-filter-uses-SourceAlpha.svg second-filter-uses-SourceAlpha.svg
|
||||
== second-filter-uses-SourceGraphic.svg simple-chain-ref.svg
|
||||
== simple-chain.svg simple-chain-ref.svg
|
||||
|
@ -0,0 +1,29 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg id="svg-root"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<g id="testmeta">
|
||||
<title>SVG Filter Chains: Second Filter Uses SourceAlpha</title>
|
||||
<link rel="copyright"
|
||||
href="http://www.w3.org/Graphics/SVG/Test/Copyright"/>
|
||||
<link rel="license"
|
||||
href="http://www.w3.org/Consortium/Legal/2008/03-bsd-license.html"/>
|
||||
<link rel="author"
|
||||
title="Max Vujovic"
|
||||
href="mailto:mvujovic@adobe.com"/>
|
||||
<link rel="help"
|
||||
href="http://dev.w3.org/fxtf/filters/#FilterPrimitiveSubRegion"/>
|
||||
<metadata class="flags">namespace svg</metadata>
|
||||
</g>
|
||||
|
||||
<g id="test-body-content">
|
||||
<filter id="blur">
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
</filter>
|
||||
<rect x="100" y="100" width="100" height="100" filter="url(#blur)" fill="#00ff00"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 969 B |
@ -0,0 +1,49 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg id="svg-root"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<g id="testmeta">
|
||||
<title>SVG Filter Chains: Second Filter Uses SourceAlpha</title>
|
||||
<link rel="copyright"
|
||||
href="http://www.w3.org/Graphics/SVG/Test/Copyright"/>
|
||||
<link rel="license"
|
||||
href="http://www.w3.org/Consortium/Legal/2008/03-bsd-license.html"/>
|
||||
<link rel="author"
|
||||
title="Max Vujovic"
|
||||
href="mailto:mvujovic@adobe.com"/>
|
||||
<link rel="help"
|
||||
href="http://dev.w3.org/fxtf/filters/#FilterPrimitiveSubRegion"/>
|
||||
<link rel="match"
|
||||
href="second-filter-uses-SourceAlpha.svg" />
|
||||
<metadata class="flags">namespace svg</metadata>
|
||||
<desc class="assert">
|
||||
In an SVG filter chain, this test verifies that a filter receives the
|
||||
correct SourceAlpha input from the previous filter in the chain. If the
|
||||
test passes, you should see a blurred green square.
|
||||
</desc>
|
||||
</g>
|
||||
|
||||
<g id="test-body-content">
|
||||
<filter id="blur">
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
</filter>
|
||||
<filter id="add-green">
|
||||
<!--
|
||||
This filter receives transparent black and the alpha channel of the
|
||||
previous blur filter. Then, it adds to the green channel where the alpha
|
||||
channel is set, resulting in a blurred green square.
|
||||
-->
|
||||
<feComponentTransfer in="SourceAlpha">
|
||||
<feFuncR type="identity"/>
|
||||
<feFuncG type="table" tableValues="1 1"/>
|
||||
<feFuncB type="identity"/>
|
||||
<feFuncA type="identity"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
<rect x="100" y="100" width="100" height="100" filter="url(#blur) url(#add-green)" fill="red"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -34,6 +34,7 @@ nsSVGFilterInstance::nsSVGFilterInstance(const nsStyleFilter& aFilter,
|
||||
mTargetBBox(aTargetBBox),
|
||||
mUserSpaceToFilterSpaceScale(aUserSpaceToFilterSpaceScale),
|
||||
mFilterSpaceToUserSpaceScale(aFilterSpaceToUserSpaceScale),
|
||||
mSourceAlphaAvailable(false),
|
||||
mInitialized(false) {
|
||||
|
||||
// Get the filter frame.
|
||||
@ -288,9 +289,46 @@ GetLastResultIndex(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs)
|
||||
numPrimitiveDescrs - 1;
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsSVGFilterInstance::GetOrCreateSourceAlphaIndex(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs)
|
||||
{
|
||||
// If the SourceAlpha index has already been determined or created for this
|
||||
// SVG filter, just return it.
|
||||
if (mSourceAlphaAvailable)
|
||||
return mSourceAlphaIndex;
|
||||
|
||||
// If this is the first filter in the chain, we can just use the
|
||||
// kPrimitiveIndexSourceAlpha keyword to refer to the SourceAlpha of the
|
||||
// original image.
|
||||
if (mSourceGraphicIndex < 0) {
|
||||
mSourceAlphaIndex = FilterPrimitiveDescription::kPrimitiveIndexSourceAlpha;
|
||||
mSourceAlphaAvailable = true;
|
||||
return mSourceAlphaIndex;
|
||||
}
|
||||
|
||||
// Otherwise, create a primitive description to turn the previous filter's
|
||||
// output into a SourceAlpha input.
|
||||
FilterPrimitiveDescription descr(PrimitiveType::ToAlpha);
|
||||
descr.SetInputPrimitive(0, mSourceGraphicIndex);
|
||||
|
||||
const FilterPrimitiveDescription& sourcePrimitiveDescr =
|
||||
aPrimitiveDescrs[mSourceGraphicIndex];
|
||||
descr.SetPrimitiveSubregion(sourcePrimitiveDescr.PrimitiveSubregion());
|
||||
descr.SetIsTainted(sourcePrimitiveDescr.IsTainted());
|
||||
|
||||
ColorSpace colorSpace = sourcePrimitiveDescr.OutputColorSpace();
|
||||
descr.SetInputColorSpace(0, colorSpace);
|
||||
descr.SetOutputColorSpace(colorSpace);
|
||||
|
||||
aPrimitiveDescrs.AppendElement(descr);
|
||||
mSourceAlphaIndex = aPrimitiveDescrs.Length() - 1;
|
||||
mSourceAlphaAvailable = true;
|
||||
return mSourceAlphaIndex;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGFilterInstance::GetSourceIndices(nsSVGFE* aPrimitiveElement,
|
||||
const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
|
||||
nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
|
||||
const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable,
|
||||
nsTArray<int32_t>& aSourceIndices)
|
||||
{
|
||||
@ -305,7 +343,7 @@ nsSVGFilterInstance::GetSourceIndices(nsSVGFE* aPrimitiveElement,
|
||||
if (str.EqualsLiteral("SourceGraphic")) {
|
||||
sourceIndex = mSourceGraphicIndex;
|
||||
} else if (str.EqualsLiteral("SourceAlpha")) {
|
||||
sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexSourceAlpha;
|
||||
sourceIndex = GetOrCreateSourceAlphaIndex(aPrimitiveDescrs);
|
||||
} else if (str.EqualsLiteral("FillPaint")) {
|
||||
sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexFillPaint;
|
||||
} else if (str.EqualsLiteral("StrokePaint")) {
|
||||
|
@ -173,6 +173,16 @@ private:
|
||||
*/
|
||||
gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
|
||||
|
||||
/**
|
||||
* Appends a new FilterPrimitiveDescription to aPrimitiveDescrs that
|
||||
* converts the FilterPrimitiveDescription at mSourceGraphicIndex into
|
||||
* a SourceAlpha input for the next FilterPrimitiveDescription.
|
||||
*
|
||||
* The new FilterPrimitiveDescription zeros out the SourceGraphic's RGB
|
||||
* channels and keeps the alpha channel intact.
|
||||
*/
|
||||
int32_t GetOrCreateSourceAlphaIndex(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs);
|
||||
|
||||
/**
|
||||
* Finds the index in aPrimitiveDescrs of each input to aPrimitiveElement.
|
||||
* For example, if aPrimitiveElement is:
|
||||
@ -181,7 +191,7 @@ private:
|
||||
* FilterPrimitiveDescription representing "another-primitive".
|
||||
*/
|
||||
nsresult GetSourceIndices(nsSVGFE* aPrimitiveElement,
|
||||
const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
|
||||
nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
|
||||
const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable,
|
||||
nsTArray<int32_t>& aSourceIndices);
|
||||
|
||||
@ -240,6 +250,18 @@ private:
|
||||
*/
|
||||
int32_t mSourceGraphicIndex;
|
||||
|
||||
/**
|
||||
* The index of the FilterPrimitiveDescription that this SVG filter should use
|
||||
* as its SourceAlpha, or the SourceAlpha keyword index if this is the first
|
||||
* filter in a chain.
|
||||
*/
|
||||
int32_t mSourceAlphaIndex;
|
||||
|
||||
/**
|
||||
* SourceAlpha is available if GetOrCreateSourceAlphaIndex has been called.
|
||||
*/
|
||||
int32_t mSourceAlphaAvailable;
|
||||
|
||||
bool mInitialized;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user