void SVGFEGaussianBlurElement::GaussianBlur(const Image* aSource, const Image* aTarget, const nsIntRect& aDataRect, uint32_t aDX, uint32_t aDY) { NS_ASSERTION(nsIntRect(0, 0, aTarget->mImage->Width(), aTarget->mImage->Height()).Contains(aDataRect), "aDataRect out of bounds"); nsAutoArrayPtr<uint8_t> tmp(new uint8_t[aTarget->mImage->GetDataSize()]); if (!tmp) return; memset(tmp, 0, aTarget->mImage->GetDataSize()); bool alphaOnly = AreAllColorChannelsZero(aTarget); const uint8_t* sourceData = aSource->mImage->Data(); uint8_t* targetData = aTarget->mImage->Data(); uint32_t stride = aTarget->mImage->Stride(); if (aDX == 0) { CopyDataRect(tmp, sourceData, stride, aDataRect); } else { int32_t longLobe = aDX/2; int32_t shortLobe = (aDX & 1) ? longLobe : longLobe - 1; for (int32_t major = aDataRect.y; major < aDataRect.YMost(); ++major) { int32_t ms = major*stride; BoxBlur(sourceData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, shortLobe, alphaOnly); BoxBlur(tmp + ms, targetData + ms, 4, aDataRect.x, aDataRect.XMost(), shortLobe, longLobe, alphaOnly); BoxBlur(targetData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, longLobe, alphaOnly); } } if (aDY == 0) { CopyDataRect(targetData, tmp, stride, aDataRect); } else { int32_t longLobe = aDY/2; int32_t shortLobe = (aDY & 1) ? longLobe : longLobe - 1; for (int32_t major = aDataRect.x; major < aDataRect.XMost(); ++major) { int32_t ms = major*4; BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, shortLobe, alphaOnly); BoxBlur(targetData + ms, tmp + ms, stride, aDataRect.y, aDataRect.YMost(), shortLobe, longLobe, alphaOnly); BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, longLobe, alphaOnly); } } }
void main() { \ FragColor = BoxBlur(); \ }";
void OuterGlowStyle::operator() (Pixels destPixels, Pixels stencilPixels) { if (!active) return; //int const width = stencilPixels.getWidth (); //int const height = stencilPixels.getHeight (); SharedTable <Colour> table = colours.createLookupTable (); Map2D <int> dist (stencilPixels.getWidth (), stencilPixels.getHeight ()); Map2D <int> temp (stencilPixels.getWidth (), stencilPixels.getHeight ()); if (precise) { LayerStyles::DistanceMap () ( Pixels::Map2D (stencilPixels), temp, stencilPixels.getWidth (), stencilPixels.getHeight (), size); #if 0 DistanceTransform::Meijster::calculateAntiAliased ( RenderPixelAntiAliased ( destPixels, opacity, spread, size, table), GetMask (stencilPixels), stencilPixels.getWidth (), stencilPixels.getHeight (), DistanceTransform::Meijster::EuclideanMetric ()); #endif for (int y = 0; y < temp.getRows (); ++y) { for (int x = 0; x < temp.getCols (); ++x) { int const v = temp (x, y); if (v > 0) temp (x, y) = (255 - v) * 256; } } } else { // "Softer" LayerStyles::BoxBlurAndDilateSettings bd (size, spread); LayerStyles::GrayscaleDilation () ( Pixels::Map2D (stencilPixels), stencilPixels.getWidth (), stencilPixels.getHeight (), dist, stencilPixels.getWidth (), stencilPixels.getHeight (), 0, 0, bd.getDilatePixels ()); BoxBlur () (dist, temp, temp.getCols (), temp.getRows (), bd.getBoxBlurRadius ()); } // Fill // PixelARGB c (0); for (int y = 0; y < temp.getRows (); ++y) { for (int x = 0; x < temp.getCols (); ++x) { int const v = (temp (x, y) + 128) / 256; PixelRGB& dest (*((PixelRGB*)destPixels.getPixelPointer (x, y))); c.setAlpha (uint8(v)); dest.blend (c); } } }