mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 467518. Interpret gfxBlur's border radius properly, as the actual boundary of the shadow, not the box-blur size. r=vlad
This commit is contained in:
parent
10f2d6de05
commit
d980ae8005
@ -186,6 +186,48 @@ BoxBlurVertical(unsigned char* aInput,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ComputeLobes(PRInt32 aRadius, PRInt32 aLobes[3][2])
|
||||||
|
{
|
||||||
|
PRInt32 major, minor, final;
|
||||||
|
|
||||||
|
/* See http://www.w3.org/TR/SVG/filters.html#feGaussianBlur for
|
||||||
|
* some notes about approximating the Gaussian blur with box-blurs.
|
||||||
|
* The comments below are in the terminology of that page.
|
||||||
|
*/
|
||||||
|
PRInt32 z = aRadius/3;
|
||||||
|
switch (aRadius % 3) {
|
||||||
|
case 0:
|
||||||
|
// aRadius = z*3; choose d = 2*z + 1
|
||||||
|
major = minor = final = z;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// aRadius = z*3 + 1
|
||||||
|
// This is a tricky case since there is no value of d which will
|
||||||
|
// yield a radius of exactly aRadius. If d is odd, i.e. d=2*k + 1
|
||||||
|
// for some integer k, then the radius will be 3*k. If d is even,
|
||||||
|
// i.e. d=2*k, then the radius will be 3*k - 1.
|
||||||
|
// So we have to choose values that don't match the standard
|
||||||
|
// algorithm.
|
||||||
|
major = z + 1;
|
||||||
|
minor = final = z;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// aRadius = z*3 + 2; choose d = 2*z + 2
|
||||||
|
major = final = z + 1;
|
||||||
|
minor = z;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NS_ASSERTION(major + minor + final == aRadius,
|
||||||
|
"Lobes don't sum to the right length");
|
||||||
|
|
||||||
|
aLobes[0][0] = major;
|
||||||
|
aLobes[0][1] = minor;
|
||||||
|
aLobes[1][0] = minor;
|
||||||
|
aLobes[1][1] = major;
|
||||||
|
aLobes[2][0] = final;
|
||||||
|
aLobes[2][1] = final;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
||||||
{
|
{
|
||||||
@ -196,12 +238,6 @@ gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
|||||||
|
|
||||||
// no need to do all this if not blurring
|
// no need to do all this if not blurring
|
||||||
if (mBlurRadius.width != 0 || mBlurRadius.height != 0) {
|
if (mBlurRadius.width != 0 || mBlurRadius.height != 0) {
|
||||||
// A blur radius of 1 achieves nothing (1/2 = 0 in int terms),
|
|
||||||
// but we still want a blur!
|
|
||||||
// XXX this may not be appropriate... perhaps just use actuall Gaussian here?
|
|
||||||
mBlurRadius.width = PR_MAX(mBlurRadius.width, 2);
|
|
||||||
mBlurRadius.height = PR_MAX(mBlurRadius.height, 2);
|
|
||||||
|
|
||||||
nsTArray<unsigned char> tempAlphaDataBuf;
|
nsTArray<unsigned char> tempAlphaDataBuf;
|
||||||
if (!tempAlphaDataBuf.SetLength(mImageSurface->GetDataSize()))
|
if (!tempAlphaDataBuf.SetLength(mImageSurface->GetDataSize()))
|
||||||
return; // OOM
|
return; // OOM
|
||||||
@ -211,19 +247,19 @@ gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
|||||||
PRInt32 rows = mImageSurface->Height();
|
PRInt32 rows = mImageSurface->Height();
|
||||||
|
|
||||||
if (mBlurRadius.width > 0) {
|
if (mBlurRadius.width > 0) {
|
||||||
PRInt32 longLobe = mBlurRadius.width / 2;
|
PRInt32 lobes[3][2];
|
||||||
PRInt32 shortLobe = (mBlurRadius.width & 1) ? longLobe : longLobe - 1;
|
ComputeLobes(mBlurRadius.width, lobes);
|
||||||
BoxBlurHorizontal(boxData, tmpData, longLobe, shortLobe, stride, rows);
|
BoxBlurHorizontal(boxData, tmpData, lobes[0][0], lobes[0][1], stride, rows);
|
||||||
BoxBlurHorizontal(tmpData, boxData, shortLobe, longLobe, stride, rows);
|
BoxBlurHorizontal(tmpData, boxData, lobes[1][0], lobes[1][1], stride, rows);
|
||||||
BoxBlurHorizontal(boxData, tmpData, longLobe, longLobe, stride, rows);
|
BoxBlurHorizontal(boxData, tmpData, lobes[2][0], lobes[2][1], stride, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mBlurRadius.height > 0) {
|
if (mBlurRadius.height > 0) {
|
||||||
PRInt32 longLobe = mBlurRadius.height / 2;
|
PRInt32 lobes[3][2];
|
||||||
PRInt32 shortLobe = (mBlurRadius.height & 1) ? longLobe : longLobe - 1;
|
ComputeLobes(mBlurRadius.height, lobes);
|
||||||
BoxBlurVertical(tmpData, boxData, longLobe, shortLobe, stride, rows);
|
BoxBlurVertical(tmpData, boxData, lobes[0][0], lobes[0][1], stride, rows);
|
||||||
BoxBlurVertical(boxData, tmpData, shortLobe, longLobe, stride, rows);
|
BoxBlurVertical(boxData, tmpData, lobes[1][0], lobes[1][1], stride, rows);
|
||||||
BoxBlurVertical(tmpData, boxData, longLobe, longLobe, stride, rows);
|
BoxBlurVertical(tmpData, boxData, lobes[2][0], lobes[2][1], stride, rows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +277,8 @@ gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gfxFloat GAUSSIAN_SCALE_FACTOR = 3 * sqrt(2 * M_PI) / 4;
|
// Blur radius is approximately 3/2 times the box-blur size
|
||||||
|
static const gfxFloat GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * (3/2);
|
||||||
|
|
||||||
gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
|
gfxIntSize gfxAlphaBoxBlur::CalculateBlurRadius(const gfxPoint& aStd)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user