void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture, unsigned /* exposedEdges */) { GraphicsContext* context = currentContext(); if (!context) return; const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture); ImageBuffer* image = textureImageBuffer.m_image.get(); OwnPtr<ImageBuffer> maskedImage; if (maskTexture && maskTexture->isValid()) { const BitmapTextureImageBuffer* mask = static_cast<const BitmapTextureImageBuffer*>(maskTexture); maskedImage = ImageBuffer::create(maskTexture->contentSize()); GraphicsContext* maskContext = maskedImage->context(); maskContext->drawImageBuffer(image, ColorSpaceDeviceRGB, IntPoint::zero(), CompositeCopy); if (opacity < 1) { maskContext->setAlpha(opacity); opacity = 1; } maskContext->drawImageBuffer(mask->m_image.get(), ColorSpaceDeviceRGB, IntPoint::zero(), CompositeDestinationIn); image = maskedImage.get(); } context->save(); context->setAlpha(opacity); #if ENABLE(3D_RENDERING) context->concat3DTransform(matrix); #else context->concatCTM(matrix.toAffineTransform()); #endif context->drawImageBuffer(image, ColorSpaceDeviceRGB, targetRect); context->restore(); }
void FEComposite::platformApplySoftware() { FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) { ByteArray* dstPixelArray = createPremultipliedImageResult(); if (!dstPixelArray) return; IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<ByteArray> srcPixelArray = in->asPremultipliedImage(effectADrawingRect); IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); in2->copyPremultipliedImage(dstPixelArray, effectBDrawingRect); arithmetic(srcPixelArray.get(), dstPixelArray, m_k1, m_k2, m_k3, m_k4); return; } ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); FloatRect srcRect = FloatRect(0, 0, -1, -1); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); break; case FECOMPOSITE_OPERATOR_IN: { GraphicsContextStateSaver stateSaver(*filterContext); filterContext->clipToImageBuffer(in2->asImageBuffer(), drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); break; } case FECOMPOSITE_OPERATOR_OUT: filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR); break; default: break; } }
void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r, bool useLowQualityScale) { // Clear the dirty rect m_dirtyRect = FloatRect(); if (context.paintingDisabled()) return; if (m_context) { if (!paintsIntoCanvasBuffer() && !document().printing()) return; m_context->paintRenderingResultsToCanvas(); } if (hasCreatedImageBuffer()) { ImageBuffer* imageBuffer = buffer(); if (imageBuffer) { if (m_presentedImage) { ImageOrientationDescription orientationDescription; #if ENABLE(CSS_IMAGE_ORIENTATION) orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation()); #endif context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription, useLowQualityScale)); } else context.drawImageBuffer(*imageBuffer, snappedIntRect(r), useLowQualityScale); } } #if ENABLE(WEBGL) if (is3D()) static_cast<WebGLRenderingContextBase*>(m_context.get())->markLayerComposited(); #endif }
void FEOffset::apply(Filter* filter) { m_in->apply(filter); if (!m_in->resultImage()) return; GraphicsContext* filterContext = getEffectContext(); if (!filterContext) return; setIsAlphaImage(m_in->isAlphaImage()); FloatRect sourceImageRect = filter->sourceImageRect(); sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); if (filter->effectBoundingBoxMode()) { m_dx *= sourceImageRect.width(); m_dy *= sourceImageRect.height(); } m_dx *= filter->filterResolution().width(); m_dy *= filter->filterResolution().height(); FloatRect dstRect = FloatRect(m_dx + m_in->scaledSubRegion().x() - scaledSubRegion().x(), m_dy + m_in->scaledSubRegion().y() - scaledSubRegion().y(), m_in->scaledSubRegion().width(), m_in->scaledSubRegion().height()); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, dstRect); }
void FEComposite::apply(Filter* filter) { m_in->apply(filter); m_in2->apply(filter); if (!m_in->resultImage() || !m_in2->resultImage()) return; GraphicsContext* filterContext = getEffectContext(); if (!filterContext) return; FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); break; case FECOMPOSITE_OPERATOR_IN: filterContext->save(); filterContext->clipToImageBuffer(m_in2->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion())); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); filterContext->restore(); break; case FECOMPOSITE_OPERATOR_OUT: filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR); break; case FECOMPOSITE_OPERATOR_ARITHMETIC: { IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); RefPtr<ImageData> imageData(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); CanvasPixelArray* srcPixelArrayB(imageData->data()); arithmetic(srcPixelArrayA, srcPixelArrayB, m_k1, m_k2, m_k3, m_k4); resultImage()->putPremultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint()); } break; default: break; } }
void BitmapTextureImageBuffer::applyFilters(const BitmapTexture& contentTexture, const FilterOperations& filters) { RefPtr<FilterEffectRenderer> renderer = FilterEffectRenderer::create(); renderer->setSourceImageRect(FloatRect(FloatPoint::zero(), contentTexture.size())); // The document parameter is only needed for CSS shaders. renderer->build(0 /*document */, filters); renderer->allocateBackingStoreIfNeeded(); GraphicsContext* context = renderer->inputContext(); context->drawImageBuffer(static_cast<const BitmapTextureImageBuffer&>(contentTexture).m_image.get(), ColorSpaceDeviceRGB, IntPoint::zero()); renderer->apply(); m_image->context()->drawImageBuffer(renderer->output(), ColorSpaceDeviceRGB, renderer->outputRect()); }
void SourceAlpha::platformApplySoftware() { ImageBuffer* resultImage = createImageBufferResult(); Filter* filter = this->filter(); if (!resultImage || !filter->sourceImage()) return; setIsAlphaImage(true); FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); GraphicsContext* filterContext = resultImage->context(); filterContext->fillRect(imageRect, Color::black, ColorSpaceDeviceRGB); filterContext->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint(), CompositeDestinationIn); }
void FEBlend::applySoftware() { #if HAVE(ARM_NEON_INTRINSICS) if (applySoftwareNEON()) return; #endif FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); ImageBuffer* imageBuffer = in->asImageBuffer(); ImageBuffer* imageBuffer2 = in2->asImageBuffer(); ASSERT(imageBuffer); ASSERT(imageBuffer2); filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeSourceOver, m_mode); }
void FEMerge::platformApplySoftware() { unsigned size = numberOfEffectInputs(); ASSERT(size > 0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); for (unsigned i = 0; i < size; ++i) { FilterEffect* in = inputEffect(i); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); } }
void FilterEffectRendererHelper::applyFilterEffect(GraphicsContext& destinationContext) { ASSERT(m_haveFilterEffect && m_renderLayer->filterRenderer()); FilterEffectRenderer* filter = m_renderLayer->filterRenderer(); filter->inputContext()->restore(); filter->apply(); // Get the filtered output and draw it in place. LayoutRect destRect = filter->outputRect(); destRect.move(m_paintOffset.x(), m_paintOffset.y()); destinationContext.drawImageBuffer(filter->output(), m_renderLayer->renderer().style().colorSpace(), snapRectToDevicePixels(destRect, m_renderLayer->renderer().document().deviceScaleFactor())); filter->clearIntermediateResults(); }
void FEOffset::apply() { FilterEffect* in = inputEffect(0); in->apply(); if (!in->resultImage()) return; GraphicsContext* filterContext = effectContext(); if (!filterContext) return; setIsAlphaImage(in->isAlphaImage()); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); Filter* filter = this->filter(); drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegion); }
void FEMerge::apply(Filter* filter) { ASSERT(!m_mergeInputs.isEmpty()); for (unsigned i = 0; i < m_mergeInputs.size(); i++) { m_mergeInputs[i]->apply(filter); if (!m_mergeInputs[i]->resultImage()) return; } GraphicsContext* filterContext = getEffectContext(); if (!filterContext) return; for (unsigned i = 0; i < m_mergeInputs.size(); i++) { FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->scaledSubRegion()); filterContext->drawImageBuffer(m_mergeInputs[i]->resultImage(), DeviceColorSpace, destRect); } }
void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned /* exposedEdges */) { GraphicsContext* context = currentContext(); if (!context) return; const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture); ImageBuffer* image = textureImageBuffer.m_image.get(); context->save(); context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver); context->setAlpha(opacity); #if ENABLE(3D_RENDERING) context->concat3DTransform(matrix); #else context->concatCTM(matrix.toAffineTransform()); #endif context->drawImageBuffer(image, ColorSpaceDeviceRGB, targetRect); context->restore(); }
void FETile::apply() { // FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise. #if ENABLE(SVG) FilterEffect* in = inputEffect(0); in->apply(); if (!in->resultImage()) return; GraphicsContext* filterContext = effectContext(); if (!filterContext) return; setIsAlphaImage(in->isAlphaImage()); // Source input needs more attention. It has the size of the filterRegion but gives the // size of the cutted sourceImage back. This is part of the specification and optimization. FloatRect tileRect = in->maxEffectRect(); FloatPoint inMaxEffectLocation = tileRect.location(); FloatPoint maxEffectLocation = maxEffectRect().location(); if (in->filterEffectType() == FilterEffectTypeSourceInput) { Filter* filter = this->filter(); tileRect = filter->filterRegion(); tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); } OwnPtr<ImageBuffer> tileImage; if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB)) return; GraphicsContext* tileImageContext = tileImage->context(); tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); tileImageContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true); AffineTransform patternTransform; patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); pattern->setPatternSpaceTransform(patternTransform); filterContext->setFillPattern(pattern); filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); #endif }
void SourceAlpha::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); Filter* filter = this->filter(); if (!resultImage || !filter->sourceImage()) return; setIsAlphaImage(true); FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); GraphicsContext* filterContext = resultImage->context(); filterContext->fillRect(imageRect, Color::black); IntRect srcRect = filter->sourceImageRect(); if (ImageBuffer* sourceImageBuffer = filter->sourceImage()) { filterContext->drawImageBuffer(sourceImageBuffer, FloatRect(IntPoint(srcRect.location() - absolutePaintRect().location()), sourceImageBuffer->size()), 0, CompositeDestinationIn); } }
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)); 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(); 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->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, ColorSpaceDeviceRGB); resultContext->setCompositeOperation(CompositeDestinationOver); resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion); }
void FETile::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; setIsAlphaImage(in->isAlphaImage()); // Source input needs more attention. It has the size of the filterRegion but gives the // size of the cutted sourceImage back. This is part of the specification and optimization. FloatRect tileRect = in->maxEffectRect(); FloatPoint inMaxEffectLocation = tileRect.location(); FloatPoint maxEffectLocation = maxEffectRect().location(); if (in->filterEffectType() == FilterEffectTypeSourceInput) { Filter* filter = this->filter(); tileRect = filter->absoluteFilterRegion(); } OwnPtr<ImageBufferSurface> surface; IntSize intTileSize = roundedIntSize(tileRect.size()); surface = adoptPtr(new UnacceleratedImageBufferSurface(intTileSize)); OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(surface.release()); if (!tileImage) return; GraphicsContext* tileImageContext = tileImage->context(); tileImageContext->scale(FloatSize(intTileSize.width() / tileRect.width(), intTileSize.height() / tileRect.height())); tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); tileImageContext->drawImageBuffer(in->asImageBuffer(), in->absolutePaintRect().location()); RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(CopyBackingStore), true, true); AffineTransform patternTransform; patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); pattern->setPatternSpaceTransform(patternTransform); GraphicsContext* filterContext = resultImage->context(); filterContext->setFillPattern(pattern); filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); }
void PDFDocumentImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op, BlendMode, ImageOrientationDescription) { if (!m_document || !m_hasPage) return; updateCachedImageIfNeeded(context, dstRect, srcRect); { GraphicsContextStateSaver stateSaver(context); context.setCompositeOperation(op); if (m_cachedImageBuffer) context.drawImageBuffer(*m_cachedImageBuffer, dstRect); else { transformContextForPainting(context, dstRect, srcRect); drawPDFPage(context); } } if (imageObserver()) imageObserver()->didDraw(this); }
void FETile::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; setIsAlphaImage(in->isAlphaImage()); // Source input needs more attention. It has the size of the filterRegion but gives the // size of the cutted sourceImage back. This is part of the specification and optimization. FloatRect tileRect = in->maxEffectRect(); FloatPoint inMaxEffectLocation = tileRect.location(); FloatPoint maxEffectLocation = maxEffectRect().location(); if (in->filterEffectType() == FilterEffectTypeSourceInput) { Filter* filter = this->filter(); tileRect = filter->absoluteFilterRegion(); tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); } OwnPtr<ImageBuffer> tileImage; if (!SVGRenderingContext::createImageBufferForPattern(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB, filter()->renderingMode())) return; GraphicsContext* tileImageContext = tileImage->context(); tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(CopyBackingStore), true, true); AffineTransform patternTransform; patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); pattern->setPatternSpaceTransform(patternTransform); GraphicsContext* filterContext = resultImage->context(); filterContext->setFillPattern(pattern); filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); }
void FEColorMatrix::apply() { FilterEffect* in = inputEffect(0); in->apply(); if (!in->resultImage()) return; GraphicsContext* filterContext = effectContext(); if (!filterContext) return; filterContext->drawImageBuffer(in->resultImage(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); IntRect imageRect(IntPoint(), resultImage()->size()); RefPtr<ImageData> imageData = resultImage()->getUnmultipliedImageData(imageRect); ByteArray* pixelArray = imageData->data()->data(); switch (m_type) { case FECOLORMATRIX_TYPE_UNKNOWN: break; case FECOLORMATRIX_TYPE_MATRIX: effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_SATURATE: effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_HUEROTATE: effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray, m_values); break; case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray, m_values); setIsAlphaImage(true); break; } resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint()); }
void FEComposite::applySoftware() { FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) { Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); if (!dstPixelArray) return; IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectADrawingRect); IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); in2->copyPremultipliedImage(dstPixelArray, effectBDrawingRect); platformArithmeticSoftware(srcPixelArray.get(), dstPixelArray, m_k1, m_k2, m_k3, m_k4); return; } ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); ImageBuffer* imageBuffer = in->asImageBuffer(); ImageBuffer* imageBuffer2 = in2->asImageBuffer(); ASSERT(imageBuffer); ASSERT(imageBuffer2); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect())); break; case FECOMPOSITE_OPERATOR_IN: { // Applies only to the intersected region. IntRect destinationRect = in->absolutePaintRect(); destinationRect.intersect(in2->absolutePaintRect()); destinationRect.intersect(absolutePaintRect()); if (destinationRect.isEmpty()) break; FloatRect sourceRect(IntPoint(destinationRect.x() - in->absolutePaintRect().x(), destinationRect.y() - in->absolutePaintRect().y()), destinationRect.size()); FloatRect source2Rect(IntPoint(destinationRect.x() - in2->absolutePaintRect().x(), destinationRect.y() - in2->absolutePaintRect().y()), destinationRect.size()); destinationRect.move(-absolutePaintRect().x(), -absolutePaintRect().y()); filterContext->drawImageBuffer(imageBuffer2, destinationRect, &source2Rect); filterContext->drawImageBuffer(imageBuffer, destinationRect, &sourceRect, CompositeSourceIn); break; } case FECOMPOSITE_OPERATOR_OUT: filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect()), 0, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeXOR); break; default: break; } }