Bug 1092634 - Let feColorMatrix and feComponentTransfer generate output outside their input's bounds. r=Bas

This makes the color matrix and component transfer Moz2D filters generate an infinite output, which is then cropped to the primitive's filter primitive subregion by a subsequent crop filter node. This still gives us different behavior than other browser when the primitive subregion is overridden using the x/y/width/height attributes - other browsers either ignore those completely (IE) or only let them crop the default subregion (which is defined to be the same as the input subregion) and not enlargen it - but I'll fix that in a separate bug.
This commit is contained in:
Markus Stange 2014-11-18 17:21:19 -05:00
Родитель 566dc5b315
Коммит cacfe982d9
7 изменённых файлов: 113 добавлений и 1 удалений

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

@ -1460,6 +1460,9 @@ FilterNodeColorMatrixSoftware::RequestFromInputsForRect(const IntRect &aRect)
IntRect
FilterNodeColorMatrixSoftware::GetOutputRectInRect(const IntRect& aRect)
{
if (mMatrix._54 > 0.0f) {
return aRect;
}
return GetInputRectInRect(IN_COLOR_MATRIX_IN, aRect);
}
@ -1808,7 +1811,10 @@ FilterNodeComponentTransferSoftware::RequestFromInputsForRect(const IntRect &aRe
IntRect
FilterNodeComponentTransferSoftware::GetOutputRectInRect(const IntRect& aRect)
{
return GetInputRectInRect(IN_TRANSFER_IN, aRect);
if (mDisableA) {
return GetInputRectInRect(IN_TRANSFER_IN, aRect);
}
return aRect;
}
int32_t

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

@ -1389,6 +1389,42 @@ FilterSupport::ComputeResultChangeRegion(const FilterDescription& aFilter,
return resultChangeRegions[resultChangeRegions.Length() - 1];
}
static float
ResultOfZeroUnderTransferFunction(const AttributeMap& aFunctionAttributes)
{
switch (aFunctionAttributes.GetUint(eComponentTransferFunctionType)) {
case SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
{
const nsTArray<float>& tableValues =
aFunctionAttributes.GetFloats(eComponentTransferFunctionTableValues);
if (tableValues.Length() < 2) {
return 0.0f;
}
return tableValues[0];
}
case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
{
const nsTArray<float>& tableValues =
aFunctionAttributes.GetFloats(eComponentTransferFunctionTableValues);
if (tableValues.Length() < 1) {
return 0.0f;
}
return tableValues[0];
}
case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
return aFunctionAttributes.GetFloat(eComponentTransferFunctionIntercept);
case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
return aFunctionAttributes.GetFloat(eComponentTransferFunctionOffset);
case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY:
default:
return 0.0f;
}
}
nsIntRegion
FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& aDescription,
const nsTArray<nsIntRegion>& aInputExtents)
@ -1439,6 +1475,27 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a
return ThebesIntRect(aDescription.PrimitiveSubregion());
}
case PrimitiveType::ColorMatrix:
{
if (atts.GetUint(eColorMatrixType) == (uint32_t)SVG_FECOLORMATRIX_TYPE_MATRIX) {
const nsTArray<float>& values = atts.GetFloats(eColorMatrixValues);
if (values[19] > 0.0f) {
return ThebesIntRect(aDescription.PrimitiveSubregion());
}
}
return aInputExtents[0];
}
case PrimitiveType::ComponentTransfer:
{
AttributeMap functionAttributes =
atts.GetAttributeMap(eComponentTransferFunctionA);
if (ResultOfZeroUnderTransferFunction(functionAttributes) > 0.0f) {
return ThebesIntRect(aDescription.PrimitiveSubregion());
}
return aInputExtents[0];
}
case PrimitiveType::Turbulence:
case PrimitiveType::Image:
{

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

@ -0,0 +1,10 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="f" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
<feFlood flood-color="lime"/>
</filter>
<rect width="100" height="100" filter="url(#f)"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 348 B

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

@ -0,0 +1,13 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="f" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
<feColorMatrix type="matrix" values="0 0 0 0 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 1"/>
</filter>
<rect width="100" height="100" filter="url(#f)"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 525 B

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

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="f" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="200">
<feComponentTransfer>
<feFuncR type="table" tableValues="0 0" />
<feFuncG type="table" tableValues="1 1" />
<feFuncB type="table" tableValues="0 0" />
<feFuncA type="table" tableValues="1 1" />
</feComponentTransfer>
</filter>
<rect width="100" height="100" filter="url(#f)"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 563 B

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

@ -0,0 +1,7 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="200" fill="lime"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 213 B

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

@ -116,3 +116,7 @@ fuzzy(2,2659) skip-if(d2d) == feSpecularLighting-1.svg feSpecularLighting-1-ref.
== fePointLight-zoomed-page.svg fePointLight-zoomed-page-ref.svg
== feTurbulence-offset.svg feTurbulence-offset-ref.svg
== outside-sourcegraphic-1.svg outside-sourcegraphic-ref.svg
== outside-sourcegraphic-2.svg outside-sourcegraphic-ref.svg
== outside-sourcegraphic-3.svg outside-sourcegraphic-ref.svg