Bug 678250 - Filter bounds rounded before scaling so small filters may be too large. r=roc

This commit is contained in:
Robert Longson 2011-08-15 19:41:57 +01:00
Родитель c3b3536b52
Коммит 06c1893a2d
7 изменённых файлов: 41 добавлений и 20 удалений

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

@ -0,0 +1,18 @@
<svg width="100%" height="100%" preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Testcase for scaled filter with non-integer x and y and objectBoundingBox</title>
<defs>
<filter id="filter" filterUnits="objectBoundingBox" x="0.5" y="0.5" width="0.25" height="0.25">
<feFlood flood-color="red" width="1" height="1" />
</filter>
</defs>
<rect width="100%" height="100%" fill="lime"/>
<g transform="scale(400)">
<rect width="1" height="1" filter="url(#filter)" />
</g>
<rect x="200" y="200" width="100" height="100" fill="lime" />
</svg>

После

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

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

@ -5,7 +5,7 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.0">
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=461863 -->
<desc>
This test checks that transforms and filtering a decedent of a
This test checks that transforms and filtering a descendant of a
filtered element interact correctly.
</desc>
<filter id="a"><feGaussianBlur stdDeviation="0.001"/></filter>

До

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

После

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

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

@ -2,8 +2,7 @@
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg width="100%" height="100%"
viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Reference for objectBoundingBox with fePointLight</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=544742 -->
@ -16,7 +15,7 @@
</filter>
</defs>
<g stroke="black" transform="translate(20 20)">
<g transform="translate(20 20)">
<rect width="40" height="20" filter="url(#light)" fill="black" stroke="none"/>
</g>

До

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

После

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

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

@ -2,8 +2,7 @@
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg width="100%" height="100%"
viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Testcase for objectBoundingBox with fePointLight</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=544742 -->

До

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

После

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

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

@ -111,6 +111,7 @@ random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
== filter-basic-03.svg pass.svg
== filter-foreignObject-01.svg pass.svg
== filter-invalidation-01.svg pass.svg
== filter-scaled-01.svg pass.svg
== filter-translated-01.svg filter-translated-01-ref.svg
== filters-and-group-opacity-01.svg filters-and-group-opacity-01-ref.svg
== foreignObject-01.svg pass.svg

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

@ -135,7 +135,6 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
gfxRect filterRegion = nsSVGUtils::GetRelativeRect(filterUnits,
filter->mLengthAttributes, bbox, aTarget);
filterRegion.RoundOut();
if (filterRegion.Width() <= 0 || filterRegion.Height() <= 0) {
// 0 disables rendering, < 0 is error. dispatch error console warning
@ -149,13 +148,19 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
// temporary offscreen surface that we'll paint into):
gfxIntSize filterRes;
if (filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].IsExplicitlySet()) {
PRInt32 filterResX =
filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].GetAnimValue(nsSVGIntegerPair::eFirst);
PRInt32 filterResY =
filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES].GetAnimValue(nsSVGIntegerPair::eSecond);
// XXX what if the 'filterRes' attribute has a bad value? error console warning?
const nsSVGIntegerPair& filterResAttrs =
filter->mIntegerPairAttributes[nsSVGFilterElement::FILTERRES];
if (filterResAttrs.IsExplicitlySet()) {
PRInt32 filterResX = filterResAttrs.GetAnimValue(nsSVGIntegerPair::eFirst);
PRInt32 filterResY = filterResAttrs.GetAnimValue(nsSVGIntegerPair::eSecond);
if (filterResX <= 0 || filterResY <= 0) {
// 0 disables rendering, < 0 is error. dispatch error console warning?
return;
}
filterRegion.Scale(filterResX, filterResY);
filterRegion.RoundOut();
filterRegion.Scale(1.0 / filterResX, 1.0 / filterResY);
// We don't care if this overflows, because we can handle upscaling/
// downscaling to filterRes
PRBool overflow;
@ -168,16 +173,15 @@ nsAutoFilterInstance::nsAutoFilterInstance(nsIFrame *aTarget,
// Match filterRes as closely as possible to the pixel density of the nearest
// outer 'svg' device space:
float scale = nsSVGUtils::MaxExpansion(userToDeviceSpace);
filterRegion.Scale(scale);
filterRegion.RoundOut();
// We don't care if this overflows, because we can handle upscaling/
// downscaling to filterRes
PRBool overflow;
filterRes = nsSVGUtils::ConvertToSurfaceSize(filterRegion.Size() * scale,
filterRes = nsSVGUtils::ConvertToSurfaceSize(filterRegion.Size(),
&overflow);
}
if (filterRes.width <= 0 || filterRes.height <= 0) {
// 0 disables rendering, < 0 is error. dispatch error console warning?
return;
filterRegion.Scale(1.0 / scale);
}
// XXX we haven't taken account of the fact that filterRegion may be

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

@ -371,7 +371,7 @@ nsSVGFilterInstance::BuildSourceImages()
// (In theory it would be better to minimize error by having filtered SVG
// graphics temporarily paint to user space when painting the sources and
// only set a user space to filter space transform on the gfxContext
// (since that would elliminate the transform multiplications from user
// (since that would eliminate the transform multiplications from user
// space to device space and back again). However, that would make the
// code more complex while being hard to get right without introducing
// subtle bugs, and in practice it probably makes no real difference.)