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);
    }
  }
}
Beispiel #2
0
							void main() { \
							FragColor = BoxBlur(); \
							}";
Beispiel #3
0
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);
    }
  }
}