void FEDropShadow::platformApplySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Filter& filter = this->filter(); FloatSize blurRadius(2 * filter.applyHorizontalScale(m_stdX), 2 * filter.applyVerticalScale(m_stdY)); blurRadius.scale(filter.filterScale()); FloatSize offset(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); FloatRect drawingRegionWithOffset(drawingRegion); drawingRegionWithOffset.move(offset); ImageBuffer* sourceImage = in->asImageBuffer(); if (!sourceImage) return; GraphicsContext& resultContext = resultImage->context(); resultContext.setAlpha(m_shadowOpacity); resultContext.drawImageBuffer(*sourceImage, drawingRegionWithOffset); resultContext.setAlpha(1); ShadowBlur contextShadow(blurRadius, offset, m_shadowColor); // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. IntRect shadowArea(IntPoint(), resultImage->internalSize()); RefPtr<Uint8ClampedArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, ImageBuffer::BackingStoreCoordinateSystem); contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); resultImage->putByteArray(Premultiplied, srcPixelArray.get(), shadowArea.size(), shadowArea, IntPoint(), ImageBuffer::BackingStoreCoordinateSystem); resultContext.setCompositeOperation(CompositeSourceIn); resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor); resultContext.setCompositeOperation(CompositeDestinationOver); resultImage->context().drawImageBuffer(*sourceImage, drawingRegion); }
void FEDropShadow::platformApplySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Filter* filter = this->filter(); FloatSize blurRadius(filter->applyHorizontalScale(m_stdX), filter->applyVerticalScale(m_stdY)); FloatSize offset(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); FloatRect drawingRegionWithOffset(drawingRegion); drawingRegionWithOffset.move(offset); ImageBuffer* sourceImage = in->asImageBuffer(); ASSERT(sourceImage); GraphicsContext* resultContext = resultImage->context(); ASSERT(resultContext); resultContext->setAlpha(m_shadowOpacity); resultContext->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegionWithOffset); resultContext->setAlpha(1); ShadowBlur contextShadow(blurRadius, offset, m_shadowColor, ColorSpaceDeviceRGB); // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. IntRect shadowArea(IntPoint(), resultImage->size()); RefPtr<ByteArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea); contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); resultImage->putPremultipliedImageData(srcPixelArray.get(), shadowArea.size(), shadowArea, IntPoint()); resultContext->setCompositeOperation(CompositeSourceIn); resultContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor, ColorSpaceDeviceRGB); resultContext->setCompositeOperation(CompositeDestinationOver); resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion); }