FloatRect FilterEffect::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { FloatRect requestedRect = originalRequestedRect; // Filters in SVG clip to primitive subregion, while CSS doesn't. if (m_clipsToBounds) requestedRect.intersect(maxEffectRect()); // We may be called multiple times if result is used more than once. Return // quickly if if nothing new is required. if (absolutePaintRect().contains(enclosingIntRect(requestedRect))) return requestedRect; FloatRect inputRect = mapPaintRect(requestedRect, false); FloatRect inputUnion; unsigned size = m_inputEffects.size(); for (unsigned i = 0; i < size; ++i) inputUnion.unite(m_inputEffects.at(i)->determineAbsolutePaintRect(inputRect)); inputUnion = mapPaintRect(inputUnion, true); if (affectsTransparentPixels() || !size) { inputUnion = requestedRect; } else { // Rect may have inflated. Re-intersect with request. inputUnion.intersect(requestedRect); } addAbsolutePaintRect(inputUnion); return inputUnion; }
void FEColorMatrix::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); SkAutoTUnref<SkColorFilter> filter(createColorFilter(m_type, m_values.data())); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return; SkPaint paint; paint.setColorFilter(filter); paint.setXfermodeMode(SkXfermode::kSrc_Mode); resultImage->context()->drawBitmap(nativeImage->bitmap(), drawingRegion.x(), drawingRegion.y(), &paint); if (affectsTransparentPixels()) { IntRect fullRect = IntRect(IntPoint(), absolutePaintRect().size()); resultImage->context()->clipOut(drawingRegion); resultImage->context()->fillRect(fullRect, Color(m_values[4], m_values[9], m_values[14], m_values[19])); } return; }
void FEComponentTransfer::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return; unsigned char rValues[256], gValues[256], bValues[256], aValues[256]; getValues(rValues, gValues, bValues, aValues); IntRect destRect = drawingRegionOfInputImage(in->absolutePaintRect()); SkPaint paint; paint.setColorFilter(SkTableColorFilter::CreateARGB(aValues, rValues, gValues, bValues))->unref(); paint.setXfermodeMode(SkXfermode::kSrc_Mode); resultImage->context()->drawBitmap(nativeImage->bitmap(), destRect.x(), destRect.y(), &paint); if (affectsTransparentPixels()) { IntRect fullRect = IntRect(IntPoint(), absolutePaintRect().size()); resultImage->context()->clipOut(destRect); resultImage->context()->fillRect(fullRect, Color(rValues[0], gValues[0], bValues[0], aValues[0])); } }
FloatRect FilterEffect::applyBounds(const FloatRect& rect) const { // Filters in SVG clip to primitive subregion, while CSS doesn't. if (!clipsToBounds()) return rect; FloatRect bounds = absoluteBounds(); if (affectsTransparentPixels()) return bounds; return intersection(rect, bounds); }